@quo-systems/quo 0.1.1 → 0.2.1
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/SPEC.md +259 -129
- package/dist/being/index.d.ts +1 -1
- package/dist/being/index.js +1 -1
- package/dist/being/silence.d.ts +6 -1
- package/dist/being/silence.js +25 -7
- package/dist/being/types.d.ts +8 -4
- package/dist/being/types.js +1 -1
- package/dist/conformance/beings.d.ts +1 -1
- package/dist/conformance/beings.js +5 -5
- package/dist/conformance/estate.js +23 -34
- package/dist/conformance/index.js +14 -12
- package/dist/harbor/core.d.ts +7 -1
- package/dist/harbor/core.js +25 -2
- package/dist/harbor/dial.js +7 -1
- package/dist/harbor/memory.d.ts +5 -1
- package/dist/harbor/memory.js +7 -2
- package/dist/ward/door.d.ts +6 -2
- package/dist/ward/door.js +55 -35
- package/dist/ward/ground.d.ts +4 -1
- package/dist/ward/heirs.d.ts +4 -2
- package/dist/ward/heirs.js +20 -3
- package/dist/ward/owner.d.ts +5 -3
- package/dist/ward/owner.js +55 -16
- package/dist/ward/partition.d.ts +6 -0
- package/dist/ward/partition.js +2 -0
- package/dist/ward/seal.d.ts +3 -1
- package/dist/ward/seal.js +6 -2
- package/dist/ward/stance.d.ts +2 -2
- package/dist/ward/stance.js +21 -12
- package/dist/ward/ward.js +37 -12
- package/package.json +19 -31
- package/src/being/index.ts +1 -1
- package/src/being/silence.ts +26 -8
- package/src/being/types.ts +13 -3
- package/src/conformance/beings.ts +5 -5
- package/src/conformance/estate.ts +22 -36
- package/src/conformance/index.ts +14 -12
- package/src/harbor/core.ts +24 -2
- package/src/harbor/dial.ts +7 -1
- package/src/harbor/memory.ts +6 -1
- package/src/ward/door.ts +54 -32
- package/src/ward/ground.ts +6 -2
- package/src/ward/heirs.ts +20 -5
- package/src/ward/owner.ts +54 -16
- package/src/ward/partition.ts +10 -0
- package/src/ward/seal.ts +8 -5
- package/src/ward/stance.ts +20 -14
- package/src/ward/ward.ts +37 -13
- package/vectors/framing.json +7 -1
package/SPEC.md
CHANGED
|
@@ -94,9 +94,13 @@ gap in Quo or a leak into the ward. The shape is `Ground` in
|
|
|
94
94
|
|
|
95
95
|
Returned:
|
|
96
96
|
|
|
97
|
-
- **The door.** One call: sealed bytes in, sealed bytes out
|
|
97
|
+
- **The door.** One call: sealed bytes in, sealed bytes out, and one bit
|
|
98
|
+
beside them, `heard`: whether a key this door holds spoke. Always bytes:
|
|
98
99
|
when the ask did not open, the reply is silence sealed to whatever ephemeral
|
|
99
|
-
pk the bytes carried, and noise when they carried none.
|
|
100
|
+
pk the bytes carried, and noise when they carried none. The bit is all a
|
|
101
|
+
harbor learns from an arrival, never a reason: a pk that only ever brings
|
|
102
|
+
strangers' bytes is the harbor's to rate or refuse, and what a bound key
|
|
103
|
+
hears is sealed to its own lid.
|
|
100
104
|
- **The ask.** One call: method and args in, object or silence out.
|
|
101
105
|
In-process and unsealed. This is the one unsealed ask in Quo, and the only
|
|
102
106
|
way a ward is piloted. Judgment, catching, and the return table are not
|
|
@@ -132,10 +136,10 @@ stance
|
|
|
132
136
|
occupants.invite(id) -> invitation | null awaitable: a key is minted
|
|
133
137
|
occupants.remove(id) -> nothing
|
|
134
138
|
|
|
135
|
-
standings.knock(invitation, method?, args?, wanted?) -> object | silence |
|
|
139
|
+
standings.knock(invitation, method?, args?, wanted?) -> object | silence | word
|
|
136
140
|
standings.take(id, invitation) -> id | null awaitable: it waits for the relation
|
|
137
141
|
standings[id] -> standing | undefined
|
|
138
|
-
standings[id].ask(method?, args?, wanted?) -> object | silence |
|
|
142
|
+
standings[id].ask(method?, args?, wanted?) -> object | silence | word
|
|
139
143
|
standings.remove(id) -> nothing
|
|
140
144
|
|
|
141
145
|
wanted = { time? } what this one ask may spend, in milliseconds. optional,
|
|
@@ -150,16 +154,16 @@ Return table.
|
|
|
150
154
|
| | null | the id already names a record, occupant or standing, or is a reserved word |
|
|
151
155
|
| remove(id) | nothing | always. removing what is not there is nothing |
|
|
152
156
|
| knock(inv, m, a, w) | object | the far being answered |
|
|
153
|
-
| | silence | no ward claims the invitation, or
|
|
154
|
-
| |
|
|
155
|
-
| | unreached
|
|
157
|
+
| | silence | no ward claims the invitation, or another consumed it, or the far being chose silence |
|
|
158
|
+
| | word | why not, when the far door or her own ward can say: removed, absent, unannounced, repeated, |
|
|
159
|
+
| | | threw, unreached, late, invitation. see "Silence, the words, error" |
|
|
156
160
|
| take(id, inv) | id | she knocked with this invitation and was answered, and the id is fresh |
|
|
157
161
|
| | null | no answered knock on this invitation, or the id already names a record, or is a reserved word |
|
|
158
162
|
| standings[id] | standing | the record exists |
|
|
159
163
|
| | undefined | it does not. not an error |
|
|
160
164
|
| ask(m, a, w) | object | she answered |
|
|
161
|
-
| | silence | she
|
|
162
|
-
| |
|
|
165
|
+
| | silence | she chose to say nothing, or bytes came back that are not Quo's |
|
|
166
|
+
| | word | why not: removed, absent, repeated, threw, unreached, late, dropped |
|
|
163
167
|
|
|
164
168
|
Ask, knock, invite and take are awaitable. Async where the language has it,
|
|
165
169
|
blocking where it does not. Every ask she makes is a new call.
|
|
@@ -175,16 +179,19 @@ The asker has three shapes and no fourth, and nothing else ever reaches her.
|
|
|
175
179
|
`OWNER` and `PUBLIC` are reserved words: invite and take refuse them, so no
|
|
176
180
|
occupant can ever wear either name.
|
|
177
181
|
|
|
178
|
-
## Silence,
|
|
182
|
+
## Silence, the words, error
|
|
179
183
|
|
|
180
|
-
Three
|
|
181
|
-
that can go wrong ends in one of them, and a being who knows the three
|
|
182
|
-
needs a fourth.
|
|
184
|
+
Three kinds of answer to "no object came back", and only three. Everything in
|
|
185
|
+
Quo that can go wrong ends in one of them, and a being who knows the three
|
|
186
|
+
never needs a fourth.
|
|
183
187
|
|
|
184
188
|
```
|
|
185
189
|
error an object. hers. { error: ... }, or any shape her output schema declares.
|
|
186
|
-
silence the ward's
|
|
187
|
-
|
|
190
|
+
silence the ward's silence. bytes came back, or would have, and said nothing.
|
|
191
|
+
it is what a stranger hears, and what she hears when
|
|
192
|
+
the far being chose to say nothing.
|
|
193
|
+
a word the ward's word. one of nine, said only to someone the ward can name,
|
|
194
|
+
and never to a stranger: why no object came.
|
|
188
195
|
```
|
|
189
196
|
|
|
190
197
|
- An **error** is an ordinary answer. Quo never reads it, never makes it,
|
|
@@ -192,42 +199,75 @@ unreached the ward's word. not heard. nothing came back. nothing is known to
|
|
|
192
199
|
`{ error: 'unknown ask' }` for an ask she did not declare or hid; the
|
|
193
200
|
owner's asks answer error objects for what they refuse; both are hers to
|
|
194
201
|
read like any object.
|
|
195
|
-
- **Silence**
|
|
196
|
-
and
|
|
202
|
+
- **Silence** names no reason, by law. It is what the door says to bytes it
|
|
203
|
+
cannot admit, so that a stranger learns nothing, and what a being says
|
|
204
|
+
when she chooses to say nothing. It is not blindly retryable: the far
|
|
205
|
+
being may have done the work and the answer was lost.
|
|
206
|
+
- **A word** names the reason. It is said to a key the door has bound, sealed
|
|
207
|
+
to that key's lid, or by her own ward to her, in process. Nobody else ever
|
|
208
|
+
hears one. A word is not an object: it carries nothing but its name, a
|
|
209
|
+
being cannot make one, and one that comes out of a being is read as her
|
|
210
|
+
having thrown.
|
|
211
|
+
|
|
212
|
+
The nine words, and who says them:
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
the door, to a key it has bound, on the wire as { quo: word }
|
|
216
|
+
removed the relation this key spoke for was removed by the being who invited it
|
|
217
|
+
absent the being who invited it did not come back this run; her cells wait
|
|
218
|
+
unannounced the knock announced no key of her own, so it bound nothing
|
|
219
|
+
repeated the number was already honoured, or is at or below the span
|
|
220
|
+
threw she threw, or answered a shape that is not hers to make
|
|
221
|
+
|
|
222
|
+
her own ward, to her, and never on the wire
|
|
223
|
+
unreached no far door was reached. nothing is known to have been delivered.
|
|
224
|
+
late the wait ran out. the far door may have heard and be working still.
|
|
225
|
+
invitation the invitation is not one. nothing was sent.
|
|
226
|
+
dropped she dropped the standing, and asked on what she held. nothing was sent.
|
|
227
|
+
```
|
|
228
|
+
|
|
197
229
|
- **Unreached** is safe to retry: nothing is known to have been delivered.
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
230
|
+
In one case the far ward heard and died before it could answer, and the
|
|
231
|
+
wire says nothing about it; asking again asks under the next number and
|
|
232
|
+
is heard, so the retry is safe all the same. See Closed.
|
|
233
|
+
- **Late** is not unreached, and the difference is the whole reason there are
|
|
234
|
+
two words: a bound that expired promises nothing about delivery.
|
|
235
|
+
- **Removed**, **absent**, **unannounced** and **repeated** are refusals: the
|
|
236
|
+
ask reached no being and nothing was written. They are said only because
|
|
237
|
+
the key that asked has already proven who it is, so a reason to it is an
|
|
238
|
+
oracle to nobody. **Threw** is a choice: she was reached, and the number is
|
|
239
|
+
spent.
|
|
240
|
+
|
|
241
|
+
Who says what. A being says objects and silence, never a word: the shape is
|
|
242
|
+
the ward's, and a ward that sees one come out of a being answers `threw`. A
|
|
243
|
+
ward says all three to its own being, and on the wire objects, silence and
|
|
244
|
+
the five door words, each sealed to the lid of the key that asked; the four
|
|
245
|
+
ward words never cross, they are her own ward's and are said in process. A
|
|
246
|
+
harbor says nothing at all; it returns bytes or nothing, and does not know
|
|
247
|
+
any of these words. What it learns from an arrival is one bit, `heard`,
|
|
248
|
+
beside the bytes the door hands it: whether a key the door holds spoke. The
|
|
249
|
+
owner hears objects: a silence a being met is `{ error: 'silence' }` and a
|
|
250
|
+
word is `{ error: word }`, because the owner is piloting and an object is
|
|
211
251
|
what a shell can print. The ask pointer answers the value silence only when
|
|
212
252
|
the ward itself threw.
|
|
213
253
|
|
|
214
|
-
### What her ward
|
|
254
|
+
### What her ward says to her
|
|
215
255
|
|
|
216
|
-
Before or after the wire, her own ward answers
|
|
217
|
-
|
|
256
|
+
Before or after the wire, her own ward answers on its own in five cases,
|
|
257
|
+
and each says what it is.
|
|
218
258
|
|
|
219
259
|
```
|
|
220
260
|
S1 the invitation is not one a shape that is not a ward pk, a heir with no secret, a secret with no heir.
|
|
221
|
-
nothing is sent.
|
|
261
|
+
nothing is sent. the word is `invitation`.
|
|
222
262
|
S2 the standing is gone she held a standing, dropped it, and asked on what she held.
|
|
223
|
-
nothing is sent. an ask issued while it stood is answered.
|
|
263
|
+
nothing is sent. an ask issued while it stood is answered. the word is `dropped`.
|
|
224
264
|
S3 the wait ran out the ask's time was spent and no reply was read.
|
|
225
265
|
what comes back late is not read. the number is spent.
|
|
226
|
-
an ask still waiting at its lane when the wait ran out is never sent.
|
|
266
|
+
an ask still waiting at its lane when the wait ran out is never sent. the word is `late`.
|
|
227
267
|
S4 the reply is not one bytes came back that do not open, or are not signed by the ward they
|
|
228
|
-
were sent to, or are
|
|
229
|
-
|
|
230
|
-
S5 the far door
|
|
268
|
+
were sent to, or are none of the three reply shapes. the number is spent.
|
|
269
|
+
not Quo's bytes: silence.
|
|
270
|
+
S5 the far door answered silence, or a word, exactly as the door said it.
|
|
231
271
|
```
|
|
232
272
|
|
|
233
273
|
And unreached in two: `U1` the args are not a value, or could not be
|
|
@@ -236,69 +276,83 @@ sealed, so nothing left;
|
|
|
236
276
|
taken all the same, and the gap it leaves in the count is harmless: the door
|
|
237
277
|
honours any number above its mark.
|
|
238
278
|
|
|
239
|
-
### What the door
|
|
279
|
+
### What the door says
|
|
240
280
|
|
|
241
|
-
The door
|
|
242
|
-
the
|
|
243
|
-
|
|
244
|
-
|
|
281
|
+
The door judges thirteen cases, in this order, and the first case met is
|
|
282
|
+
the answer. The first seven are strangers: bytes the door cannot admit, met
|
|
283
|
+
with one silence whatever the case, and nothing written. The next three are
|
|
284
|
+
refusals to a key the door has bound: still nothing written, but a word,
|
|
285
|
+
because the asker has proven who it is. The last three are choices: the ask
|
|
286
|
+
reached her, so the number is spent and the keys are rotated, and what she
|
|
287
|
+
wrote in her cells is hers.
|
|
245
288
|
|
|
246
289
|
```
|
|
247
|
-
|
|
290
|
+
strangers: silence, nothing written, heard false
|
|
248
291
|
D1 the box does not open wrong padlock, garbage, too short. the reply is sealed to the lid if
|
|
249
292
|
the bytes carried one, and is noise otherwise. a lid that will not
|
|
250
293
|
take a seal, a small-order point, is no lid: noise.
|
|
251
294
|
D2 the payload is malformed by or next not 64 hex, method not a string, args not an object, seq
|
|
252
|
-
below one, time not a whole number above zero
|
|
295
|
+
below one, time not a whole number above zero, hops not a whole
|
|
296
|
+
number or at zero.
|
|
253
297
|
D3 for nobody, and nobody is home no public being on this ward.
|
|
254
298
|
D4 for nobody, signature fails the payload names a key it was not signed with.
|
|
255
|
-
D5 the heir is not held never minted here,
|
|
299
|
+
D5 the heir is not held never minted here, and not one she removed either.
|
|
256
300
|
D6 the key is not admitted not the key held for the heir, and not the key it announced. a
|
|
257
|
-
forged key, an unannounced key, a heir already spent.
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
301
|
+
forged key, an unannounced key, a heir already spent. a heir she
|
|
302
|
+
removed, under a key that was not the one she removed.
|
|
303
|
+
D7 signature fails under an admitted key, or under the key held for a heir she removed.
|
|
304
|
+
refusals to a bound key: a word, nothing written, heard true
|
|
305
|
+
D8 she is not there `removed`: the occupant record is gone, and this is the key it was
|
|
306
|
+
bound to when it went. `absent`: the being did not come back this run.
|
|
307
|
+
D9 a knock announces nothing `unannounced`: the heir is fresh and next is null. it binds nothing.
|
|
308
|
+
D10 the number is refused `repeated`: already honoured, or at or below the span.
|
|
309
|
+
choices: the number spent, the keys rotated, heard true
|
|
310
|
+
D11 she threw `threw`
|
|
264
311
|
D12 she answered silence on a named ask, or on the empty ask. nothing at all is silence too.
|
|
265
|
-
D13 she answered
|
|
312
|
+
D13 she answered a word `threw`: a word is not hers to make.
|
|
266
313
|
```
|
|
267
314
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
315
|
+
The signature is verified before anything is written and before any word is
|
|
316
|
+
said, so a stranger cannot burn a number she could not sign for and cannot
|
|
317
|
+
hear a word she could not sign for. The public being is asked by strangers
|
|
318
|
+
only, and a stranger hears silence for whatever she then does: her choices
|
|
319
|
+
are hers, and her insides are not a stranger's to read.
|
|
320
|
+
|
|
321
|
+
A removed relation leaves the door one thing: the keys it held for that
|
|
322
|
+
heir when the id went, kept apart from the heirs under `gone` in the
|
|
323
|
+
partition, bounded, oldest out. That is what lets the door say `removed` to
|
|
324
|
+
the one party who can sign as those keys, and silence to everyone else.
|
|
325
|
+
Nothing else survives a removal.
|
|
272
326
|
|
|
273
327
|
### The law of one silence
|
|
274
328
|
|
|
275
|
-
1. Every case
|
|
276
|
-
ask came with, signed by the ward key. Same bytes, same length.
|
|
277
|
-
stranger cannot tell
|
|
278
|
-
|
|
329
|
+
1. Every stranger's case is one reply: `{ silence: true }`, sealed to the
|
|
330
|
+
lid the ask came with, signed by the ward key. Same bytes, same length.
|
|
331
|
+
A stranger cannot tell one refusal from another, nor any of them from a
|
|
332
|
+
being who chose to say nothing.
|
|
279
333
|
The door equalizes the bytes and not the time it took to write them. The
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
refused at the door. A stranger holds no standing and reaches no choice,
|
|
284
|
-
which is why the refusals are the ones made alike. Equalizing the time
|
|
285
|
-
would mean waiting out the allowance ceiling on every silence, and the
|
|
286
|
-
door will not buy that.
|
|
334
|
+
seven cases are cheap and alike. A word, to a key the door has bound, is
|
|
335
|
+
another length, and may be: whoever hears it has already proven who they
|
|
336
|
+
are.
|
|
287
337
|
2. A refusal writes nothing. No number, no key, no heir, no cell, no bind.
|
|
288
338
|
The same bytes presented again meet the same refusal, and a stranger who
|
|
289
|
-
knocks a thousand times leaves no mark.
|
|
339
|
+
knocks a thousand times leaves no mark. This holds for the three
|
|
340
|
+
refusals a bound key hears just the same: a word costs nothing.
|
|
290
341
|
3. A choice writes what a heard ask writes. The number is spent and the keys
|
|
291
342
|
rotate, so the relation goes on: the next ask on it is answered, and a
|
|
292
|
-
silence never kills a standing.
|
|
293
|
-
4. Silence
|
|
294
|
-
leaves `seen` untouched; a silent empty ask leaves `blueprint` and
|
|
295
|
-
`digest` untouched
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
343
|
+
silence or a `threw` never kills a standing.
|
|
344
|
+
4. Silence and a word leave the caller's record as it was. A silent named
|
|
345
|
+
answer leaves `seen` untouched; a silent empty ask leaves `blueprint` and
|
|
346
|
+
`digest` untouched; a word moves neither, and her keys do not rotate on
|
|
347
|
+
one.
|
|
348
|
+
5. Her ward never confuses her. Silence, a word and unreached are told apart
|
|
349
|
+
always, and by nothing else: silence is bytes the far ward wrote and
|
|
350
|
+
chose to say nothing with; a word is a reason, from the far door or her
|
|
351
|
+
own ward; unreached is the wire's nothing. A ward never answers nothing,
|
|
352
|
+
so that nothing always means unreached.
|
|
353
|
+
6. Nobody enforces what a being does with silence or a word. Each is one
|
|
354
|
+
value she compares against, and the base class hands them to her
|
|
355
|
+
unchanged.
|
|
302
356
|
|
|
303
357
|
`test/silence.test.ts` asserts every numbered line above, by its number.
|
|
304
358
|
|
|
@@ -324,15 +378,17 @@ nothing was written down that a harbor would later have to lie about. This
|
|
|
324
378
|
holds all the way down: a container read through her cells is part of her
|
|
325
379
|
cells. The guard is `src/ward/cells.ts`.
|
|
326
380
|
|
|
327
|
-
### Silence and
|
|
381
|
+
### Silence and the words
|
|
328
382
|
|
|
329
|
-
Two of the three
|
|
330
|
-
|
|
331
|
-
distinguished value. Null is an answer.
|
|
332
|
-
value, her ward's own
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
`src/being/silence.ts
|
|
383
|
+
Two of the three kinds of "no object came back". The chapter "Silence, the
|
|
384
|
+
words, error" is the whole of them; here only the values. Silence is one
|
|
385
|
+
distinguished value. Null is an answer. A word is a second kind of
|
|
386
|
+
distinguished value, her ward's own, nine of them, `unreached` among them.
|
|
387
|
+
None is an object, and none carries anything but its name. In this kit
|
|
388
|
+
silence is the symbol `quo.silence` and a word is a frozen object under the
|
|
389
|
+
symbol key `quo.word` holding its name, both from `src/being/silence.ts`;
|
|
390
|
+
`isWord` and `wordOf` read them, and `isUnreached` is the one word a being
|
|
391
|
+
asks about most.
|
|
336
392
|
|
|
337
393
|
### Blueprint, schema, digest
|
|
338
394
|
|
|
@@ -483,7 +539,8 @@ the standing is.
|
|
|
483
539
|
### The public being
|
|
484
540
|
|
|
485
541
|
A ward may have one public being, and no more. She is an ordinary being,
|
|
486
|
-
booted by the owner and marked public
|
|
542
|
+
booted by the owner and then marked public by the owner's `public` ask.
|
|
543
|
+
Arrivals for no heir reach her. Her
|
|
487
544
|
asker is `{}`: she is asked by anyone, and she can tell. She may hold
|
|
488
545
|
standings. She may invite, and an occupant of hers arrives named while
|
|
489
546
|
strangers still arrive as `{}`. A ward without a public being answers
|
|
@@ -504,6 +561,14 @@ So her answer must be safe to repeat. This is her obligation, not a gap at
|
|
|
504
561
|
the door. Anything that must happen once lives behind an invitation, where
|
|
505
562
|
there is a heir and a count.
|
|
506
563
|
|
|
564
|
+
Nothing else about her is different. Her cells, her standings and what she
|
|
565
|
+
keeps are hers, exactly as they are for every being, and Quo has no say in
|
|
566
|
+
them: she may hold a board every stranger plays on, a catalogue, a queue, or
|
|
567
|
+
nothing at all. She is an ordinary being who chose to describe herself to
|
|
568
|
+
strangers and to answer them, and that choice is the whole of what makes her
|
|
569
|
+
public. A stranger who keeps knocking is the harbor's, never hers and never
|
|
570
|
+
the door's.
|
|
571
|
+
|
|
507
572
|
### How a relation crosses wards
|
|
508
573
|
|
|
509
574
|
1. She mints an id. Her ward mints a heir for it, keeps the pk, and hands
|
|
@@ -670,13 +735,15 @@ Every arrival is judged by the door, and named by it or falls silent.
|
|
|
670
735
|
2. For nobody: find the public being, verify the signature under the key the
|
|
671
736
|
payload names, and dispatch as `{}`. Nothing is written.
|
|
672
737
|
3. For a heir: admit the signer if it is the key held for that heir or the
|
|
673
|
-
key that key announced
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
738
|
+
key that key announced, or the key held when she removed the id. Verify
|
|
739
|
+
the signature. Only then say anything or write anything: a removed
|
|
740
|
+
relation is `removed`, a being not back this run is `absent`, a knock
|
|
741
|
+
with no key is `unannounced`, a number already honoured is `repeated`,
|
|
742
|
+
and none of those writes. Else spend the number and settle the keys, so
|
|
743
|
+
a stranger cannot burn a number she could not sign for, and the same
|
|
744
|
+
bytes twice rotate nothing. Dispatch as `{ id }`.
|
|
745
|
+
4. Catch every throw and answer `threw` to a bound key, silence at the
|
|
746
|
+
public being. Treat a word coming out of a being as a throw.
|
|
680
747
|
5. On every answered named ask, run her describe for that asker in process,
|
|
681
748
|
hash it, and put the digest next to the object in the reply. One trip. A
|
|
682
749
|
describe that throws or falls silent costs the digest and nothing else.
|
|
@@ -684,7 +751,7 @@ Every arrival is judged by the door, and named by it or falls silent.
|
|
|
684
751
|
6. Answer by the same call the ask came in on.
|
|
685
752
|
|
|
686
753
|
A stranger is bytes the ward cannot admit, and every way of being one is
|
|
687
|
-
listed, with a number, under "Silence,
|
|
754
|
+
listed, with a number, under "Silence, the words, error". The public being
|
|
688
755
|
is the one door a stranger may walk through, and only because she chose it.
|
|
689
756
|
|
|
690
757
|
### Inner and outer
|
|
@@ -729,7 +796,8 @@ ask on the wire box = ephemeral X25519 pk (32) || AES-GCM( payload || si
|
|
|
729
796
|
refused at zero, and nothing sets it.
|
|
730
797
|
reply on the wire box = ephemeral X25519 pk (32) || AES-GCM( reply || signature (64) )
|
|
731
798
|
sealed to the ask's ephemeral pk, signed by the ward key
|
|
732
|
-
reply = JSON { object, seen } | { silence: true }
|
|
799
|
+
reply = JSON { object, seen } | { silence: true } | { quo: word }
|
|
800
|
+
word: removed | absent | unannounced | repeated | threw. only to a key the door bound.
|
|
733
801
|
```
|
|
734
802
|
|
|
735
803
|
Nothing rides outside the box, and `to` is the reason to say so. A heir is
|
|
@@ -759,6 +827,14 @@ silent. It keeps every being it booted, builds every stance, mints every
|
|
|
759
827
|
key, seals every ask that leaves, and unseals every one that arrives. Its
|
|
760
828
|
beings trust it blindly. It trusts its harbor the same way.
|
|
761
829
|
|
|
830
|
+
Only a ward moves. A being has no address of her own and never leaves the
|
|
831
|
+
ward that booted her: her peers hold a standing at a ward pk, and what they
|
|
832
|
+
trust is that ward's word about an id, never the being under it. So which
|
|
833
|
+
beings share a ward is settled when they are booted, and a ward migrates
|
|
834
|
+
whole, with everyone in it, or not at all. To move one being would be to ask
|
|
835
|
+
every peer to trust a ward they never accepted, and asking that is what an
|
|
836
|
+
invitation is.
|
|
837
|
+
|
|
762
838
|
Its ward is itself. It boots itself as the first being in its own map, under
|
|
763
839
|
its own pk, and its own stance is built by the same code that builds every
|
|
764
840
|
being's. Its cells are its partition, all the way down.
|
|
@@ -819,6 +895,8 @@ partition
|
|
|
819
895
|
answered <ward>:<heir> | public:<ward> -> true knocked and answered
|
|
820
896
|
minted the last eight pks her side minted
|
|
821
897
|
heirs heir pk -> { being, id, current, announced, fresh, mark, spent } the door's view of every occupant
|
|
898
|
+
gone heir pk -> { current, announced } the keys held when an id was removed, bounded, so their
|
|
899
|
+
holder hears `removed` and nobody else hears a thing
|
|
822
900
|
public the one public being's key, or null
|
|
823
901
|
```
|
|
824
902
|
|
|
@@ -852,8 +930,9 @@ before the restart can be taken after it; a door that restarts still refuses
|
|
|
852
930
|
what it already honoured.
|
|
853
931
|
|
|
854
932
|
A constructor that throws on a restart takes only herself down: she is
|
|
855
|
-
absent this run, no door, so
|
|
856
|
-
|
|
933
|
+
absent this run, no door, so `absent` at her door to the keys she bound and
|
|
934
|
+
silence to strangers, and her cells sit untouched waiting for the run that
|
|
935
|
+
can read them. The ward is up and so is everyone
|
|
857
936
|
else. A class the harbor no longer knows is the same absence, and so is a
|
|
858
937
|
class the harbor holds at a body the cells were not written for: which body
|
|
859
938
|
a ward reboots on is the harbor's decision, and a ward cannot tell an old
|
|
@@ -883,19 +962,25 @@ become one.
|
|
|
883
962
|
The root is not an occupant. It holds no heir, no key, no invitation. The
|
|
884
963
|
ward names every arrival on the ask `{ id: 'OWNER' }`, the third asker of the
|
|
885
964
|
ward-to-being edge, and answers it as such; an owner at the door arrives as
|
|
886
|
-
her id. What an owner can do is exactly what a being cannot: boot,
|
|
887
|
-
relation into a being of the ward,
|
|
888
|
-
carry no allowance of
|
|
965
|
+
her id. What an owner can do is exactly what a being cannot: boot, mark the
|
|
966
|
+
public being, place a relation into a being of the ward, take one out of
|
|
967
|
+
her, and take her out of the ward. The root's asks carry no allowance of
|
|
968
|
+
their own. The ward is a being to her owner: the empty ask is her describe,
|
|
969
|
+
and each ask in it carries a description and an input naming its fields, as
|
|
970
|
+
a being's asks do, so that a side renders the owner's asks the way it
|
|
971
|
+
renders anyone's and holds no list of its own.
|
|
889
972
|
|
|
890
973
|
```
|
|
891
|
-
ask() -> { asks: [boot, invite, knock, remove],
|
|
974
|
+
ask() -> { asks: [boot, public, invite, knock, remove, unboot],
|
|
892
975
|
notes: { pk, beings: { key: { class, public, digest } } } }
|
|
893
|
-
ask('boot', { key, class
|
|
976
|
+
ask('boot', { key, class }) -> { booted: key } | { error }
|
|
977
|
+
ask('public', { key }) -> { public: key } | { error }
|
|
894
978
|
ask('invite', { being, id }) -> invitation | null | { error }
|
|
895
979
|
ask('knock', { being | { boot: class, key },
|
|
896
980
|
id, invitation, method?, args?, wanted? })
|
|
897
981
|
-> { taken: id | null, answer } | { error: 'silence' | 'unreached' | ... }
|
|
898
982
|
ask('remove', { being, id }) -> { removed: id } | { error }
|
|
983
|
+
ask('unboot', { being }) -> { unbooted: key, removed: [id, ...] } | { error }
|
|
899
984
|
anything else -> { error: 'unknown ask' }
|
|
900
985
|
```
|
|
901
986
|
|
|
@@ -903,9 +988,15 @@ anything else -> { error: 'unknown ask' }
|
|
|
903
988
|
spend, and saying nothing is the ward's default, exactly as for a being.
|
|
904
989
|
- The describe runs every being's own describe as `OWNER` and hashes it; a
|
|
905
990
|
being that throws or falls silent there shows a null digest.
|
|
906
|
-
- Boot refuses a key already booted
|
|
907
|
-
|
|
908
|
-
|
|
991
|
+
- Boot refuses a key already booted and a class the harbor does not know; a
|
|
992
|
+
boot that made nobody leaves the partition as it found it. A throw at
|
|
993
|
+
birth is that boot's error, and nothing half-lives.
|
|
994
|
+
- Public marks a being already booted as the ward's one public being. It
|
|
995
|
+
refuses a key not booted, the ward's own pk, and a second public being
|
|
996
|
+
while one stands, since marking a second would leave the first holding
|
|
997
|
+
every relation she had, reachable by nobody at the bare pk and told by
|
|
998
|
+
nobody she was replaced. Marking the one already public again is
|
|
999
|
+
answered, and changes nothing.
|
|
909
1000
|
- Invite on the ward's own pk mints an owner, and only the root may ask it:
|
|
910
1001
|
from the door it is answered as an invite on nobody. The ward has
|
|
911
1002
|
occupants, its owners, and no standings: a knock for the ward itself is a
|
|
@@ -916,6 +1007,17 @@ anything else -> { error: 'unknown ask' }
|
|
|
916
1007
|
chose her class and her cells at boot; her owner may choose a relation for
|
|
917
1008
|
her too. The boot form names a being new or existing: a key already booted
|
|
918
1009
|
is a being of theirs, not a class that failed.
|
|
1010
|
+
- **Unboot is the inverse of boot, and the only way a being leaves a ward.**
|
|
1011
|
+
Every relation she holds goes with her, by the same calls she would have
|
|
1012
|
+
used herself, so an occupant of hers hears `removed` from the keys her door
|
|
1013
|
+
kept rather than meeting a being who is not there; the owner is told which
|
|
1014
|
+
ids went. Her cells and her bind table go too, because a row naming a being
|
|
1015
|
+
no door holds would boot her again on the next restart. If she was the
|
|
1016
|
+
public being the mark goes with her, and the ward answers arrivals for no
|
|
1017
|
+
heir with silence as one that never had a public being does. The ward
|
|
1018
|
+
itself is refused, for the reason knock is: it would be a ward deleting
|
|
1019
|
+
itself from inside its own map, leaving its owners bound to a door that is
|
|
1020
|
+
gone.
|
|
919
1021
|
- The owner's remove is the mirror of its knock: a relation out of a being,
|
|
920
1022
|
by id, and the id may be an occupant or a standing, since the two share
|
|
921
1023
|
one namespace. The being's own remove says nothing; the owner hears
|
|
@@ -972,7 +1074,8 @@ Not stressed with:
|
|
|
972
1074
|
from nothing else. There is no estate. The far being is sovereign: she may
|
|
973
1075
|
fall silent on the ask after the knock, and nobody is told.
|
|
974
1076
|
- Blacklists, rate limits, and what to do with a pk that keeps knocking with
|
|
975
|
-
garbage.
|
|
1077
|
+
garbage. The door says `heard` or not beside every reply; the rest is the
|
|
1078
|
+
harbor's.
|
|
976
1079
|
|
|
977
1080
|
## The harbor
|
|
978
1081
|
|
|
@@ -1004,7 +1107,9 @@ The harbor:
|
|
|
1004
1107
|
never answers nothing on its own patience; it waits, and the ward's bound
|
|
1005
1108
|
ends the ask.
|
|
1006
1109
|
- Receives bytes from the wire for a ward pk it holds, hands them to that
|
|
1007
|
-
one door, and returns what the door returned.
|
|
1110
|
+
one door, and returns what the door returned. Beside the bytes the door
|
|
1111
|
+
says whether a key it holds spoke; the harbor may count that per pk and
|
|
1112
|
+
act on it, and learns nothing more.
|
|
1008
1113
|
- Vouches: the seed stays secret, the partition is reached by this ward
|
|
1009
1114
|
alone, the ask reaches its root owner alone, the device is the harbor's
|
|
1010
1115
|
to defend. How is the device's business. Custody is this vouch: two
|
|
@@ -1123,7 +1228,10 @@ socket this harbor holds for that pk, and never onward by request. So a
|
|
|
1123
1228
|
harbor that cannot be dialed is reached through the one it dialed, by
|
|
1124
1229
|
anyone who holds a hint that its pk is there. The **dialer**,
|
|
1125
1230
|
`src/harbor/dial.ts`, is that harbor's half: one held socket to a URL, its
|
|
1126
|
-
own pks announced when the line opens
|
|
1231
|
+
own pks announced when the line opens and again whenever what this harbor
|
|
1232
|
+
holds changes, so a ward booted, adopted or dropped on a line already in hand
|
|
1233
|
+
is reachable through it without waiting for that line to fall; the listener's
|
|
1234
|
+
bound, dialed again
|
|
1127
1235
|
with a wait that doubles from a second to thirty when the line drops, and
|
|
1128
1236
|
while it is dialed it is one of the harbor's fallbacks, where a pk nobody
|
|
1129
1237
|
here knows is sent. Fallbacks are a list and a pk is tried down it in
|
|
@@ -1147,7 +1255,7 @@ class. Her ward does all of that, and she trusts it blindly: what the ward
|
|
|
1147
1255
|
names is true.
|
|
1148
1256
|
|
|
1149
1257
|
She asks her standings by method and args and gets back an object, silence,
|
|
1150
|
-
or
|
|
1258
|
+
or a word. She invites whom she wants, in her own time, and removes them
|
|
1151
1259
|
when she decides. She knocks with invitations she was given and takes the
|
|
1152
1260
|
ones she wants. She answers every ask her ward brings her with an object or
|
|
1153
1261
|
silence; an error is an ordinary object, and she never throws outward. She
|
|
@@ -1160,9 +1268,10 @@ only the ward instantiates.
|
|
|
1160
1268
|
|
|
1161
1269
|
### Her obligations
|
|
1162
1270
|
|
|
1163
|
-
1. Args are one object. A throw is
|
|
1164
|
-
|
|
1165
|
-
|
|
1271
|
+
1. Args are one object. A throw is the word `threw` outside, to whoever the
|
|
1272
|
+
door has bound, and silence to a stranger: the ward is in the middle of
|
|
1273
|
+
every call and catches, always, in every language. An error is an object
|
|
1274
|
+
her output schema declares.
|
|
1166
1275
|
2. No lifecycle. Construction with the stance is birth. A restart is silent.
|
|
1167
1276
|
3. The empty ask is hers. Who gets what blueprint is her decision. She obeys
|
|
1168
1277
|
the shape, never a content. The empty ask must be safe to repeat: her
|
|
@@ -1327,7 +1436,7 @@ alone, one JavaScript file and one declaration file per source file with
|
|
|
1327
1436
|
every relative import rewritten, and the exports map points there, types
|
|
1328
1437
|
beside default. The
|
|
1329
1438
|
build runs before every gate and every publish and is never tracked;
|
|
1330
|
-
nothing under `test/` or `
|
|
1439
|
+
nothing under `test/` or `dock/` imports it except through the package
|
|
1331
1440
|
name, which is how a consumer does. `test/package.test.ts` is the one
|
|
1332
1441
|
suite that meets the package as a stranger: it packs the tarball,
|
|
1333
1442
|
installs it into an empty folder, and imports every entry point under
|
|
@@ -1347,7 +1456,7 @@ test/ the suites.
|
|
|
1347
1456
|
vectors/ fixed inputs and outputs: the arithmetic, Quo's own framing, the frames on the wire.
|
|
1348
1457
|
```
|
|
1349
1458
|
|
|
1350
|
-
`
|
|
1459
|
+
`dock/` sits beside `src` and is not Quo: the beings, screens, model sides
|
|
1351
1460
|
and real harbors built on it, each folder with its own document. This
|
|
1352
1461
|
document does not read them, and they may not add a word to it. Its one
|
|
1353
1462
|
claim on them is that every harbor there passes `src/conformance/` untouched.
|
|
@@ -1398,11 +1507,14 @@ passes the same suite. Those tests are the checklist, not the mock.
|
|
|
1398
1507
|
on Quo actually has -- scattered wards on scattered harbors, partners and
|
|
1399
1508
|
employees invited, knocking, taken, kicked, and moving to harbors of their
|
|
1400
1509
|
own. It keeps a model of the graph, plays legal moves against it from three
|
|
1401
|
-
fixed seeds, and after every move holds
|
|
1402
|
-
ward keeps closes on both ends, that every arc in it answers when asked
|
|
1403
|
-
exactly what being that arc means
|
|
1404
|
-
|
|
1405
|
-
|
|
1510
|
+
fixed seeds, and after every move holds two things: that the ledger every
|
|
1511
|
+
ward keeps closes on both ends, and that every arc in it answers when asked
|
|
1512
|
+
exactly what being that arc means. The second is held under all three
|
|
1513
|
+
topologies, and that is the promise of Quo at a scale a scene cannot
|
|
1514
|
+
reach: the model never learns the topology, so neither may any answer. The
|
|
1515
|
+
model is the script's own bookkeeping and is never compared with itself
|
|
1516
|
+
across topologies, which would hold by construction and prove nothing. A
|
|
1517
|
+
relation is two arcs and never one edge:
|
|
1406
1518
|
the occupant is the host's, the standing is the guest's, and the model
|
|
1407
1519
|
keeps them apart because the ward does. A red run prints its seed and the
|
|
1408
1520
|
moves that got there. It is read beside one hand-written story that says in
|
|
@@ -1414,10 +1526,11 @@ passes the same suite. Those tests are the checklist, not the mock.
|
|
|
1414
1526
|
replay, a restart, and every byte on the wire inspected for anything inner.
|
|
1415
1527
|
- `test/public.test.ts`: the public being, what the door does and does not
|
|
1416
1528
|
do for her.
|
|
1417
|
-
- `test/silence.test.ts`: the chapter "Silence,
|
|
1418
|
-
numbers: the five
|
|
1419
|
-
cases of the door with a partition snapshot under each,
|
|
1420
|
-
|
|
1529
|
+
- `test/silence.test.ts`: the chapter "Silence, the words, error" by its
|
|
1530
|
+
numbers: the five cases and two unreacheds of her ward, the thirteen
|
|
1531
|
+
cases of the door with a partition snapshot under each, seven strangers
|
|
1532
|
+
met with one silence and six bound keys hearing their word, hops refused
|
|
1533
|
+
at zero, and the six lines of the law of one silence.
|
|
1421
1534
|
- `test/blueprint.test.ts`: blueprints and instantiation through a real
|
|
1422
1535
|
ward. What a boot leaves behind, what a restart brings back when the code
|
|
1423
1536
|
moved under the cells, the gate and the door, the reserved ids.
|
|
@@ -1578,6 +1691,19 @@ Decided here, so that the answer is not rediscovered:
|
|
|
1578
1691
|
the default says so with `wanted` on the ask, which is the whole of what a
|
|
1579
1692
|
being needs. An owner who wants another ceiling is asking for a different
|
|
1580
1693
|
ward.
|
|
1694
|
+
- **A leaked seed is a taken ward, and there is no succession.** The seed has
|
|
1695
|
+
one custodian, the harbor, which vouches that it stays secret; a being
|
|
1696
|
+
never touches it and no byte on the wire carries it. So it is lost only
|
|
1697
|
+
where that vouch broke, and a broken vouch is total and silent. It is not
|
|
1698
|
+
lost alone: a harbor keeps the seed and the partition under one name, and
|
|
1699
|
+
the partition holds every relation's keys, so there is no event where the
|
|
1700
|
+
address is taken and the relations are not. Nothing is left to succeed to.
|
|
1701
|
+
A succession signed by the key that speaks now is signed as well by
|
|
1702
|
+
whoever took it, and one that could not be forged would have to be
|
|
1703
|
+
committed to in advance, in the invitation, which carries nothing. The
|
|
1704
|
+
answer is a new ward, and every peer invited again as anyone is invited.
|
|
1705
|
+
Lose the seed, lose the ward; there is no recovery inside Quo, and that is
|
|
1706
|
+
the same sentence the root owner already hears.
|
|
1581
1707
|
|
|
1582
1708
|
## Glossary
|
|
1583
1709
|
|
|
@@ -1608,8 +1734,12 @@ Decided here, so that the answer is not rediscovered:
|
|
|
1608
1734
|
- **blueprint**: her interface as she chooses to show it to one asker.
|
|
1609
1735
|
- **digest**: SHA-256 over the JCS of a blueprint. Per relation.
|
|
1610
1736
|
- **seen**: the digest her ward last saw arrive with an answer.
|
|
1611
|
-
- **silence**: the far side said nothing
|
|
1612
|
-
|
|
1737
|
+
- **silence**: the far side said nothing, or the door would not admit the
|
|
1738
|
+
bytes. Names no reason. Not retryable blindly.
|
|
1739
|
+
- **word**: the ward's reason, said only to a key the door has bound or by
|
|
1740
|
+
her own ward to her. Nine: removed, absent, unannounced, repeated, threw,
|
|
1741
|
+
unreached, late, invitation, dropped.
|
|
1742
|
+
- **unreached**: the word for no far door reached. Retryable.
|
|
1613
1743
|
- **notes**: hers, inside every occupant record. Quo never reads it.
|
|
1614
1744
|
- **partition**: the ward's files. Everything durable, every secret.
|
|
1615
1745
|
- **ward record**: what a harbor keeps to boot one ward again: seed,
|