@quo-systems/quo 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/SPEC.md ADDED
@@ -0,0 +1,1595 @@
1
+ # SPEC
2
+
3
+ This is the truth of Quo, and the whole context. It assumes nothing from any
4
+ other document. It is written for the two people who work on this repository,
5
+ not for a reader outside it, and it ships with the package as the truth
6
+ the source is read against.
7
+
8
+ It carries no version and keeps no history. There is no 1.0.0 yet, so there
9
+ is nobody holding an older Quo to be compatible with, and no changelog to
10
+ write. This file is rewritten in place to say what the tree says, and when
11
+ the two disagree the fix is to move one of them, the same day. Where the tree
12
+ is behind a decision, the chapter "Where the tree stands" says so; that
13
+ 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
+ The package is published from 0.1.0 with no compatibility promise: this
16
+ document may still move under anyone holding it. At 1.0.0 it is frozen
17
+ once, and versioning starts to mean something.
18
+
19
+ ## What Quo is
20
+
21
+ Quo is a protocol that lets an object ask another object and get an answer,
22
+ without knowing whether that other object is in the same process, on the same
23
+ device, or on another planet. It works on any device and in any language that
24
+ can run code. It is three words, two of which are beings, and two edges.
25
+ Nothing else is Quo.
26
+
27
+ - **Harbor.** The program a device runs to boot wards. Owns the wire and the
28
+ operating system. Not a being. Nobody outside its device.
29
+ - **Ward.** One process of its harbor. A being plus ward functions. Keeps
30
+ beings and judges its door.
31
+ - **Being.** One ordinary object, one voice.
32
+
33
+ Each word names both the interface and the thing. There is no fourth word.
34
+
35
+ ```
36
+ device A device B
37
+ harbor A harbor B
38
+ map: pk -> door | reach map: pk -> door | reach
39
+ ward W1 (pk1) ward W3 (pk3)
40
+ being b1 being b4
41
+ standings: [shop, bank] occupants: [cust7]
42
+ occupants: [owner] being b5 public
43
+ being b2
44
+ ward W2 (pk2)
45
+ being b3
46
+ ```
47
+
48
+ - A ward is named outward by one public key, its pk, derived from its seed.
49
+ That pk routes and nothing else. A being has no pk and no address. She has
50
+ relations, named by ids that never leave her ward.
51
+ - A **standing** is a pointer a being holds to another being, through which
52
+ she asks. An **occupant** is a being she invited, whom her ward names when
53
+ she asks.
54
+ - Every relation has two keys, one minted by each side for that relation
55
+ alone. Underneath every id her ward keeps the far ward's pk, the key she
56
+ is known by in that relation, and the key the far side is known by. She
57
+ never sees them.
58
+ - The harbor routes by ward pk only. Its own pks map to doors, one per ward
59
+ it booted. Foreign pks map to whatever the device calls a reach. How a
60
+ harbor fills the foreign half is its own directory, and Quo says nothing
61
+ about it.
62
+ - b1 asking b3 and b1 asking b4 are the same act inside the ward. The first
63
+ never leaves harbor A. The second does. b1 cannot tell, and should not. b1
64
+ asking b2 never leaves the ward at all.
65
+ - The ward routes one thing: its own pk. Every other ward pk goes into one
66
+ call the harbor gave it, and what comes back is bytes or nothing.
67
+
68
+ The rule that closes every chapter: whatever does not fit one of the lines in
69
+ this document is not Quo's.
70
+
71
+ ## The two edges
72
+
73
+ Quo has two edges, harbor to ward and ward to being. At each an object
74
+ crosses once, at birth, and calls cross for the rest of the ward's life.
75
+ Nothing crosses either of them but what is written here.
76
+
77
+ ### Harbor to ward
78
+
79
+ The harbor passes one object, once, at birth, and receives two pointers.
80
+
81
+ ```
82
+ ground
83
+ seed bytes, or a string. the ward derives its pk from it and nothing else.
84
+ 32 bytes are the seed; anything else is SHA-256'd to 32 bytes first.
85
+ memory the partition. the ward's files. opaque to the harbor. an object.
86
+ instantiate (class name, stance) -> object | null
87
+ carry (ward pk, bytes) -> bytes | undefined undefined: no door was reached. a throw is read the same.
88
+ random (n) -> n bytes of entropy. every key a ward mints is drawn from it.
89
+ ```
90
+
91
+ Nothing else is ever passed. A harbor that needs a sixth thing has found a
92
+ gap in Quo or a leak into the ward. The shape is `Ground` in
93
+ `src/ward/ground.ts`.
94
+
95
+ Returned:
96
+
97
+ - **The door.** One call: sealed bytes in, sealed bytes out. Always bytes:
98
+ 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
+ - **The ask.** One call: method and args in, object or silence out.
101
+ In-process and unsealed. This is the one unsealed ask in Quo, and the only
102
+ way a ward is piloted. Judgment, catching, and the return table are not
103
+ skipped: a throw inside is silence, and an unreached shape is silence.
104
+
105
+ The harbor learns the ward's pk the way anyone learns anything: it asks. The
106
+ empty ask on the ask pointer answers with the ward's describe, and the pk is
107
+ in its notes.
108
+
109
+ ### Ward to being
110
+
111
+ The ward passes one object, once, at birth, and receives one object, on
112
+ which it calls one method.
113
+
114
+ ```
115
+ in the stance at birth, once, for life
116
+ the asker at every ask
117
+ out her answer(asker, method?, args?) -> object | silence the one method the ward calls
118
+ ```
119
+
120
+ The stance is her cells, her standings to ask, and the calls to invite,
121
+ knock, take and remove. The ward builds it and hands it to the harbor's
122
+ instantiate with a class name, and receives her. No method is the empty ask,
123
+ and what she answers to it is her blueprint.
124
+
125
+ The stance, as every being in every language receives it. Nothing more is
126
+ ever offered, and nothing here may be missing.
127
+
128
+ ```
129
+ stance
130
+ cells her state. values only.
131
+
132
+ occupants.invite(id) -> invitation | null awaitable: a key is minted
133
+ occupants.remove(id) -> nothing
134
+
135
+ standings.knock(invitation, method?, args?, wanted?) -> object | silence | unreached
136
+ standings.take(id, invitation) -> id | null awaitable: it waits for the relation
137
+ standings[id] -> standing | undefined
138
+ standings[id].ask(method?, args?, wanted?) -> object | silence | unreached
139
+ standings.remove(id) -> nothing
140
+
141
+ wanted = { time? } what this one ask may spend, in milliseconds. optional,
142
+ and so is saying anything at all
143
+ ```
144
+
145
+ Return table.
146
+
147
+ | call | returns | when |
148
+ | ------------------- | ---------- | ------------------------------------------------------------------------------------------------------------ |
149
+ | invite(id) | invitation | she minted a fresh id; the occupant record exists from now |
150
+ | | null | the id already names a record, occupant or standing, or is a reserved word |
151
+ | remove(id) | nothing | always. removing what is not there is nothing |
152
+ | knock(inv, m, a, w) | object | the far being answered |
153
+ | | silence | no ward claims the invitation, or she removed the id, or another consumed it, or the far being chose silence |
154
+ | | | or the invitation is not one, or the wait ran out |
155
+ | | unreached | her ward could not reach the far door, or could not seal the args |
156
+ | take(id, inv) | id | she knocked with this invitation and was answered, and the id is fresh |
157
+ | | null | no answered knock on this invitation, or the id already names a record, or is a reserved word |
158
+ | standings[id] | standing | the record exists |
159
+ | | undefined | it does not. not an error |
160
+ | ask(m, a, w) | object | she answered |
161
+ | | silence | she, or her ward, said nothing; or the wait ran out |
162
+ | | unreached | her ward could not reach the far door, or could not seal the args |
163
+
164
+ Ask, knock, invite and take are awaitable. Async where the language has it,
165
+ blocking where it does not. Every ask she makes is a new call.
166
+
167
+ The asker has three shapes and no fourth, and nothing else ever reaches her.
168
+
169
+ - `{ id }`: her own id for the occupant at the door, the one she minted when
170
+ she invited her.
171
+ - `{}`: she is the public being of her ward, and that is how she knows.
172
+ - `{ id: 'OWNER' }`: the arrival came on the ward's ask pointer, from her
173
+ owner.
174
+
175
+ `OWNER` and `PUBLIC` are reserved words: invite and take refuse them, so no
176
+ occupant can ever wear either name.
177
+
178
+ ## Silence, unreached, error
179
+
180
+ Three words for "no object came back", and only three. Everything in Quo
181
+ that can go wrong ends in one of them, and a being who knows the three never
182
+ needs a fourth.
183
+
184
+ ```
185
+ error an object. hers. { error: ... }, or any shape her output schema declares.
186
+ silence the ward's word. heard. bytes came back, or would have, and said nothing.
187
+ unreached the ward's word. not heard. nothing came back. nothing is known to have been delivered.
188
+ ```
189
+
190
+ - An **error** is an ordinary answer. Quo never reads it, never makes it,
191
+ and never treats it apart from any other object. The base class answers
192
+ `{ error: 'unknown ask' }` for an ask she did not declare or hid; the
193
+ owner's asks answer error objects for what they refuse; both are hers to
194
+ read like any object.
195
+ - **Silence** is not blindly retryable: the far being may have done the work
196
+ and the answer was lost.
197
+ - **Unreached** is safe to retry: nothing is known to have been delivered.
198
+ It carries no reason. What she may know is that nothing came back, and
199
+ that is all. In one case the far ward heard and died before it could
200
+ answer, and the wire says nothing about it; asking again asks under the
201
+ next number and is heard, so the retry is safe all the same. See Closed.
202
+
203
+ Who says what. A being says objects and silence, never unreached: the shape
204
+ is the ward's, and a ward that sees it come out of a being reads it as
205
+ silence. A ward says all three to its own being, and only objects and
206
+ silence on the wire: unreached never crosses, it is the wire's nothing
207
+ turned into a word. A harbor says nothing at all; it returns bytes or
208
+ nothing, and does not know the word silence. The owner hears objects: a
209
+ silence a being met is `{ error: 'silence' }` and an unreached is
210
+ `{ error: 'unreached' }`, because the owner is piloting and an object is
211
+ what a shell can print. The ask pointer answers the value silence only when
212
+ the ward itself threw.
213
+
214
+ ### What her ward turns into silence
215
+
216
+ Before or after the wire, her own ward answers silence in five cases, and
217
+ tells her nothing about which.
218
+
219
+ ```
220
+ 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.
222
+ 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.
224
+ S3 the wait ran out the ask's time was spent and no reply was read.
225
+ 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.
227
+ 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 not `{ silence }` nor `{ object, seen }` with an
229
+ object present and seen a digest or null. the number is spent.
230
+ S5 the far door said silence every case in the next list.
231
+ ```
232
+
233
+ And unreached in two: `U1` the args are not a value, or could not be
234
+ sealed, so nothing left;
235
+ `U2` the harbor returned nothing, or threw, so no door was reached. The number is
236
+ taken all the same, and the gap it leaves in the count is harmless: the door
237
+ honours any number above its mark.
238
+
239
+ ### What the door turns into silence
240
+
241
+ The door answers one silence in thirteen cases. The first ten are refusals:
242
+ the ask reached no being, and nothing was written, spent, rotated or
243
+ touched. The last three are choices: the ask reached her, so the number is
244
+ spent and the keys are rotated, and what she wrote in her cells is hers.
245
+
246
+ ```
247
+ refusals
248
+ D1 the box does not open wrong padlock, garbage, too short. the reply is sealed to the lid if
249
+ the bytes carried one, and is noise otherwise. a lid that will not
250
+ take a seal, a small-order point, is no lid: noise.
251
+ 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.
253
+ D3 for nobody, and nobody is home no public being on this ward.
254
+ 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, or forgotten because the id was removed.
256
+ 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
+ D7 she is not there the occupant record is gone, or the being did not come back this run.
259
+ D8 signature fails under an admitted key.
260
+ D9 a knock announces nothing the heir is fresh and next is null. it binds nothing.
261
+ D10 the number is refused already honoured, or at or below the span.
262
+ choices
263
+ D11 she threw
264
+ D12 she answered silence on a named ask, or on the empty ask. nothing at all is silence too.
265
+ D13 she answered an unreached shape
266
+ ```
267
+
268
+ A refusal is judged in that order, and the first case met is the answer.
269
+ The signature is verified before the number is spent, so a stranger cannot
270
+ burn a number she could not sign for; a refusal at D9 or D10 has passed the
271
+ signature and still writes nothing.
272
+
273
+ ### The law of one silence
274
+
275
+ 1. Every case above is one reply: `{ silence: true }`, sealed to the lid the
276
+ ask came with, signed by the ward key. Same bytes, same length. A
277
+ stranger cannot tell a refusal from a choice, nor one refusal from
278
+ another, nor any of them from a being who chose to say nothing.
279
+ The door equalizes the bytes and not the time it took to write them. The
280
+ ten refusals are cheap and alike; a choice ran a being first, and a being
281
+ is code this document does not bound. So whoever holds a standing may
282
+ learn from a clock that she was reached and said nothing, rather than
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.
287
+ 2. A refusal writes nothing. No number, no key, no heir, no cell, no bind.
288
+ The same bytes presented again meet the same refusal, and a stranger who
289
+ knocks a thousand times leaves no mark.
290
+ 3. A choice writes what a heard ask writes. The number is spent and the keys
291
+ rotate, so the relation goes on: the next ask on it is answered, and a
292
+ silence never kills a standing.
293
+ 4. Silence leaves the caller's record as it was. A silent named answer
294
+ leaves `seen` untouched; a silent empty ask leaves `blueprint` and
295
+ `digest` untouched.
296
+ 5. Her ward never confuses her. Silence and unreached are told apart
297
+ always, and by nothing else: silence is bytes the far ward wrote, or a
298
+ bound her ward rang; unreached is the wire's nothing. A ward never
299
+ answers nothing, so that nothing always means unreached.
300
+ 6. Nobody enforces what a being does with silence. It is one value she
301
+ compares against, and the base class hands it to her unchanged.
302
+
303
+ `test/silence.test.ts` asserts every numbered line above, by its number.
304
+
305
+ ## Words and values
306
+
307
+ ### Values
308
+
309
+ Everything that crosses an edge is I-JSON (RFC 7493): args, answer,
310
+ blueprint, invitation, and whatever she caches from them. Strings are valid
311
+ Unicode. No duplicate keys. Numbers must be representable as IEEE doubles,
312
+ so integers are exact up to 2^53. Larger integers and exact decimals travel
313
+ as strings, with a schema format saying so. Bytes are base64 strings.
314
+ Nothing else is a value: no dates, no references, no functions, no native
315
+ types. An id or a standing is never a value.
316
+
317
+ Args are held to the same rule before they are sealed: an ask whose args
318
+ hold a non-value is unreached, because nothing left. Cells hold values and
319
+ refuse anything else at the moment of writing, in her own frame: a Map, a
320
+ Date, a NaN, a cyclic object, a function, an object that is not a plain one.
321
+ The refusal is a throw where she wrote it, which her ward turns into the
322
+ silence it turns every throw into. She has not answered, and
323
+ nothing was written down that a harbor would later have to lie about. This
324
+ holds all the way down: a container read through her cells is part of her
325
+ cells. The guard is `src/ward/cells.ts`.
326
+
327
+ ### Silence and unreached
328
+
329
+ Two of the three words for "no object came back". The chapter "Silence,
330
+ unreached, error" is the whole of them; here only the values. Silence is one
331
+ distinguished value. Null is an answer. Unreached is a second distinguished
332
+ value, her ward's own word. Neither is an object, and neither carries
333
+ anything. In this kit silence is the symbol `quo.silence` and unreached is a
334
+ frozen object under the symbol key `quo.unreached`, both from
335
+ `src/being/silence.ts`.
336
+
337
+ ### Blueprint, schema, digest
338
+
339
+ Nothing here is Quo's invention. Four standards, adopted whole, so that two
340
+ wards in two languages always read one blueprint the same way.
341
+
342
+ ```
343
+ blueprint
344
+ asks list of { name, description?, input: schema, output?: schema }
345
+ notes any JSON value
346
+ ```
347
+
348
+ The blueprint is the shape of an MCP tool list, plus notes. The schema is
349
+ JSON Schema draft 2020-12, the one MCP uses; typed languages generate from
350
+ it, untyped languages ignore it, and Quo writes none of it. Args are one JSON
351
+ object with named fields, as MCP passes arguments.
352
+
353
+ The digest is SHA-256, as hex, over the JCS (RFC 8785) canonical
354
+ serialization of the blueprint. Same bytes from every language. This is law:
355
+ two wards in two languages always hash one blueprint to one digest. A ward
356
+ that cannot do this is not a ward. Because only values reach a digest, a key
357
+ holding what is not a value is dropped before hashing and an array slot
358
+ holding one is null, which is what crossing an edge does to them anyway. The
359
+ reference is `src/being/digest.ts`.
360
+
361
+ Capability and state are two axes, never mixed.
362
+
363
+ ```
364
+ capability what she can be asked. blueprint. changes rarely.
365
+ hashed into the digest. learned by the empty ask.
366
+ state what she answers. answers only. may change every ask.
367
+ never hashed. never in the blueprint.
368
+ ```
369
+
370
+ A digest change means one thing: her interface changed and the cached
371
+ blueprint is wrong. Notes in the blueprint are about the interface. A being
372
+ that puts state there makes every standing refresh for nothing, and that cost
373
+ is hers.
374
+
375
+ What follows: a being's describe is an MCP tool list with no translation.
376
+ Whoever holds a ward's ask can put an MCP server in front of any being of
377
+ it, and a being's class may wrap an MCP server; neither is a ward function.
378
+ Models are occupants like anyone else. What stays Quo's: silence, unreached,
379
+ ids, invitations, knock and take, the digest rule. MCP is the description
380
+ and value layer. Quo is the relation layer.
381
+
382
+ ### Ids
383
+
384
+ An id is minted by the being, bound by the ward, permanent, and never crosses
385
+ the door. Her id for you and your id for her are unrelated. One id names one
386
+ record, and standings and occupants are one namespace: invite refuses an id a
387
+ standing holds, take refuses an id an occupant holds.
388
+
389
+ Two words are the ward's and no being may mint them: `OWNER` and `PUBLIC`,
390
+ the reserved askers of the ward-to-being edge. The ward speaks at every
391
+ being's door as `{ id: 'OWNER' }` when it runs her describe for its owner,
392
+ and an occupant wearing that name would be two parties with one face.
393
+ `PUBLIC` guards nothing today, because a public asker is `{}` and carries no
394
+ id, and it is claimed now while claiming it is free.
395
+
396
+ Three more are refused for a plainer reason: `knock`, `take` and `remove`
397
+ are the calls on `standings`, and they share that object with the ids she
398
+ takes. A standing under one of those names would be unreachable, so invite
399
+ and take refuse them like the ward's words.
400
+
401
+ ### Cells
402
+
403
+ Cells are I-JSON values. The ward may persist them. A restart is silent: she
404
+ is constructed again with the same cells.
405
+
406
+ ```
407
+ cells
408
+ standings: { id: { id, digest, blueprint, seen } } ward writes all four
409
+ occupants: { id: { id, notes } } ward writes id, she writes notes
410
+ class ward writes it at boot, so a restart finds her
411
+ anything else hers
412
+ ```
413
+
414
+ - `digest` is the hash of the blueprint she last fetched by the empty ask.
415
+ - `blueprint` is that blueprint.
416
+ - `seen` is the digest her ward last saw arrive with an answer. A silent
417
+ refresh leaves it untouched.
418
+ - `notes` is hers. Quo never reads it. Tier, expiry, kinship between an
419
+ occupant and a standing that are the same far being: all hers.
420
+
421
+ ## Relations
422
+
423
+ ### How a relation is born
424
+
425
+ There is one way in and one way back.
426
+
427
+ 1. She wants B as an occupant. She mints an id, in her own time, and asks
428
+ her ward for an invitation for it. The occupant record exists from that
429
+ moment. The invitation is a value: it goes by mail, paper, or inside the
430
+ args of some other ask. Quo does not care how.
431
+ 2. B consumes it by knocking: an ask carrying the invitation. B's ward
432
+ seals it and hands it to its harbor's carry, and her ward, which
433
+ recognises its own seal, and binds the
434
+ arrival to the id she minted. From now on every ask from B arrives as
435
+ that id. The first such ask is how she learns the invitation was
436
+ consumed. Whether it is still welcome is hers: expiry, one use, anything,
437
+ lives in her notes.
438
+ 3. If she answered, B may take her as a standing, minting B's own id for
439
+ her. That is the only moment a standing is born. Take binds B's side
440
+ only; the knock bound hers. Take before a knock, or after a silent one,
441
+ births nothing. B may also knock, say hello, and never call again. She
442
+ keeps B as an occupant until she decides otherwise. She never learns that
443
+ B walked away.
444
+ 4. B wants her to reach back? B mints an id, makes an invitation, and puts
445
+ it in the args. She knocks it and takes B if she wants. Two invitations,
446
+ two relations, each chosen by its owner.
447
+
448
+ She is always the initiator. Nobody becomes her occupant unless she invited
449
+ them. Nobody becomes her standing unless she knocked and chose to take, or
450
+ her owner knocked for her.
451
+
452
+ ### What take does
453
+
454
+ Take consumes. Until take the relation lives in a knock record, under the far
455
+ ward and the heir; from take it lives in the standing, under her id, and
456
+ never in both. Take copies the keys and the count the knock left, deletes the
457
+ knock record, and the invitation is spent for her: knocking it again is an
458
+ ask on the standing, and taking it again births nothing.
459
+
460
+ Take waits, because a relation has one line of keys and one count, and every
461
+ word spoken for it goes in order. Taken out of that order it would read
462
+ between a knock's send and its answer, and the standing would be born holding
463
+ a number the far door has already honoured and a key it has already rotated
464
+ past. So take goes in the line with the rest.
465
+
466
+ ### One relation, one lane
467
+
468
+ Every send on one relation waits for the one before it. The rotation is a
469
+ conversation: a send reads the key that speaks now, announces the next, and
470
+ moves once the far door has answered, and two sends interleaving on one
471
+ relation would read each other's half-written keys. Lanes are per relation:
472
+ beings still ask concurrently, and a slow relation never holds up another.
473
+ Before take the lane is the invitation's; after take it is the standing's,
474
+ and a knock on a taken invitation joins the standing's lane.
475
+
476
+ The keys an ask sends under are read when she calls, not when the lane
477
+ reaches her: an ask issued while the standing stood is answered even if she
478
+ drops it in the next line. An ask on a standing she has already dropped is
479
+ silence, and so is a knock on the invitation it was born on: after take the
480
+ invitation names the standing and nothing else, so it is exactly as alive as
481
+ the standing is.
482
+
483
+ ### The public being
484
+
485
+ A ward may have one public being, and no more. She is an ordinary being,
486
+ booted by the owner and marked public. Arrivals for no heir reach her. Her
487
+ asker is `{}`: she is asked by anyone, and she can tell. She may hold
488
+ standings. She may invite, and an occupant of hers arrives named while
489
+ strangers still arrive as `{}`. A ward without a public being answers
490
+ arrivals for no heir with silence.
491
+
492
+ An invitation to her is `{ ward }` alone. One with a secret and no heir is
493
+ not an invitation. She may be taken as a standing on that invitation, and
494
+ such a standing has no heir and never rotates.
495
+
496
+ She is reached without a heir, so the door keeps nothing for whoever asked:
497
+ no key it vouched for, and no count. The signature is still checked, under
498
+ whatever key signed. Once-only delivery does not reach her: the same sealed
499
+ bytes presented twice are delivered twice, and the number the payload carries
500
+ is required and honoured by nobody. A count per voice would be memory a
501
+ stranger chooses the size of, which is the thing the span exists to refuse.
502
+
503
+ So her answer must be safe to repeat. This is her obligation, not a gap at
504
+ the door. Anything that must happen once lives behind an invitation, where
505
+ there is a heir and a count.
506
+
507
+ ### How a relation crosses wards
508
+
509
+ 1. She mints an id. Her ward mints a heir for it, keeps the pk, and hands
510
+ her an invitation: her ward's pk, the heir pk, the heir secret. A value.
511
+ It goes anywhere. Rotation one.
512
+ 2. The invitation is consumed by an ask at some ward, and that ask names a
513
+ being there. Either B holds it, because a standing put it in her args,
514
+ and B knocks. Or an owner holds it, because it came by mail, and the
515
+ owner's ask knocks for a being of theirs, new or existing. There is no
516
+ third way, because a relation cannot end in thin air.
517
+ 3. B's ward mints her own key, signs the knock with the heir secret,
518
+ announces her key inside, seals the box to her ward's padlock, and
519
+ hands it to carry for the ward pk. No relation between the two wards is needed,
520
+ ever. Her ward opens its own box, admits the heir, verifies, binds the
521
+ id to B's key, and hands her the arrival as the id she minted. The heir
522
+ is spent. Rotation two.
523
+ 4. B's ward remembers the knock was answered, and lets B take. From then on
524
+ every ask from B on that standing is signed by her current key, announces
525
+ her next, and is sealed to the same padlock. Every answer rotates her.
526
+ 5. Same ward: her ward recognises its own pk and delivers without the
527
+ harbor. Same harbor: the harbor finds the pk in its own map and calls the
528
+ other door. Two harbors: the wire. The ward's code has one branch between
529
+ these, and the being has none. A same-ward knock is sealed, signed, and
530
+ judged exactly like a far one.
531
+
532
+ ## The door
533
+
534
+ ### Keys
535
+
536
+ One 32-byte seed is one key. A being's key signs and never seals. The ward's
537
+ key does both: an Ed25519 pair to sign replies, an X25519 padlock every ask
538
+ is sealed to. Beings never own a padlock.
539
+
540
+ - **The ward key** comes from the seed. Its pk on the wire is the signing pk
541
+ then the padlock, 128 hex, and it routes.
542
+ - **The heir** is the key the inviting ward mints at invite, for one id. It
543
+ keeps the heir's pk beside the id and gives the secret away. The
544
+ invitation IS the heir: ward pk, heir pk, heir secret. Rotation one: the
545
+ occupant already has a key, and the inviter chose it.
546
+ - **Her own key** is what the knocker mints at knock. She signs the knock
547
+ with the heir and announces her own key in it. The door binds the id to
548
+ her key and the heir dies as it speaks. Rotation two: from now on she
549
+ signs with a key the inviter never held. A knock that announces nothing
550
+ binds nothing.
551
+ - **Next.** Every ask she sends announces the key she will sign with next.
552
+ The door holds two pks for her: the one that may speak now, and the one
553
+ it vouched for. Whichever speaks first wins, and the other dies. There is
554
+ no rotate call: every honoured ask rotates, and a lost reply strands
555
+ nobody. Her side moves to the announced key only when an answer came back
556
+ that was not silence; the door has already moved, and admits both.
557
+
558
+ The knock is the one place where both sides cannot be brought back into
559
+ agreement by that rule alone. If the reply to the first knock is lost, the
560
+ door has spent the heir and rotated to the key she announced, and she does
561
+ not know it: knocking as the heir again would be refused for good. She cannot
562
+ learn which case she is in, so she asks, and the asking tells her. She sends
563
+ under her own key first. If the door heard, that is the key it admits and she
564
+ is answered. If it did not, the key means nothing there and the ask is
565
+ refused; a refusal at a door writes nothing, so the heir is untouched and she
566
+ knocks as the heir, as she would have. One extra round trip, in the one case
567
+ where a reply was lost. It gives a stranger nothing: whoever holds the
568
+ invitation could always knock as the heir, and her own key is admitted only
569
+ where the door already bound it to her.
570
+
571
+ Three keys per relation over its life, one rule at the door: the key I hold
572
+ for you may speak, and so may the key it announced last time, and each
573
+ number once.
574
+
575
+ Every key in a relation was minted by one side and its secret never left
576
+ that side, except the heir, which the inviter gives away and which dies the
577
+ first time it speaks. No key serves two relations. No key outlives its
578
+ relation. A ward keeps only the last eight pks a being's side minted, which
579
+ is enough to name the keys in play.
580
+
581
+ ### The count
582
+
583
+ Every ask she sends carries the next number in one unbroken count for that
584
+ relation, starting at one, and the door honours each number once. The number
585
+ rides inside the signed payload, so bytes caught on the road carry the number
586
+ they were sent under: they cannot be renumbered without breaking her
587
+ signature, and they are refused as themselves. A caller who means to ask
588
+ again asks again, under the next number, and is heard. Retry and
589
+ fire-and-forget stay hers to build; only the accident and the interception
590
+ are refused.
591
+
592
+ The door keeps the highest number honoured and which numbers below it are
593
+ spent, out to a span of sixty-four, because a door that remembered every
594
+ number ever seen would be a door with unbounded memory. A number above the
595
+ mark is honoured and moves it; a number inside the span is honoured once; a
596
+ number at or below the span is refused. The mark and the spent list are in
597
+ the partition, because a door that forgets what it honoured honours it again
598
+ after a restart.
599
+
600
+ Her side keeps the number it spoke under whether or not a reply came back. A
601
+ reply lost on the way back is a door that has already honoured the number,
602
+ and offering it twice would silence the relation for good. The count carries
603
+ over from the knock into the standing at take.
604
+
605
+ ### The allowance
606
+
607
+ Every ask carries what it may still spend: **time**, in milliseconds. It
608
+ rides inside the signed payload, so a budget caught on the road cannot be
609
+ widened by whoever caught it.
610
+
611
+ A being who says nothing gets her ward's default and never thinks about it.
612
+ A being who wants to say so passes a third argument. What she is given is
613
+ what she asked for held to what her ward allows: a number that is not a
614
+ positive whole number falls to the default rather than refusing her, and one
615
+ above the ceiling is the ceiling, silently, because the ceiling is not hers
616
+ to know. Budget is granted by a ward, never minted by a being. How wide the
617
+ default and the ceiling are is the ward's own; this ward's are thirty
618
+ seconds by default and five minutes at the ceiling, in
619
+ `src/ward/allowance.ts`.
620
+
621
+ They are two numbers and not one, because the third argument is for both
622
+ directions. A being who knows her own work asks for less on the ask she wants
623
+ back quickly, and for more on the one she knows is slow. A ceiling equal to
624
+ the default would leave her only the narrowing half, and would give the ward
625
+ no way to allow one long piece of work without making every ask that
626
+ patient.
627
+
628
+ The sender's wait has an end, and this is the one thing the ward times. The
629
+ bound covers the whole of an ask, from the moment she calls: a relation that
630
+ comes back round on itself is stopped at its own lane, before a byte is
631
+ sealed, and a bound that watched only the wire would never see it. This is
632
+ what makes three answers three. A wait that does not end is not an object,
633
+ not silence and not unreached, and before the allowance a cycle of legal asks
634
+ could produce one: A asks B, B answering asks A back, A answering asks B on
635
+ the relation the first ask still holds. Now the innermost wait gives up, the
636
+ silence unwinds outward, and the ask ends.
637
+
638
+ **A wait that ran out is silence, never unreached.** Unreached promises
639
+ nothing was delivered and is safe to ask again. A bound that expired knows no
640
+ such thing: the far door may have heard and be working still. What comes
641
+ back late is not read.
642
+
643
+ The harbor keeps a patience of its own, and the two never read each other.
644
+ What a harbor hands back as nothing came back is unreached, and unreached
645
+ says nothing was delivered: a harbor may answer it only where it knows the
646
+ bytes never arrived, no reach for that pk, a socket that would not open, a
647
+ link that is down. A harbor that sent them and then gave up knows no such
648
+ thing, and must not answer at all; the ward's bound will ring, and that is
649
+ silence, which promises nothing. A harbor that throws has answered nothing
650
+ in a louder voice, and the ward reads it as nothing: unreached. So a harbor
651
+ may hold a shorter patience than the ward for its own reasons, a socket it
652
+ wants back or a queue it will not grow, and whichever ends first ends the
653
+ ask.
654
+
655
+ The receiving door reads the allowance before anything is done under it. A
656
+ payload whose time is not a whole number above zero is malformed, D2, and
657
+ is refused as one. Nothing is spent and nothing rotates, because nothing
658
+ was heard.
659
+
660
+ Each ask is bounded on its own. The time an arriving call has left does not
661
+ bound the asks a being makes while answering it, and an ask carries no count
662
+ of doors; see Closed. Every wait still ends.
663
+
664
+ ### Judgment
665
+
666
+ Every arrival is judged by the door, and named by it or falls silent.
667
+
668
+ 1. Open the box with the ward's padlock. Read whether it is for a heir or
669
+ for nobody. Parse the payload and refuse any field of the wrong shape.
670
+ 2. For nobody: find the public being, verify the signature under the key the
671
+ payload names, and dispatch as `{}`. Nothing is written.
672
+ 3. For a heir: admit the signer if it is the key held for that heir or the
673
+ key that key announced. Find the being who minted the id and check she
674
+ still holds the occupant. Verify the signature. Only then spend the
675
+ number and settle the keys, so a stranger cannot burn a number she could
676
+ not sign for, and the same bytes twice rotate nothing. Dispatch as
677
+ `{ id }`.
678
+ 4. Catch every throw and answer silence. Treat an unreached shape coming out
679
+ of a being as silence.
680
+ 5. On every answered named ask, run her describe for that asker in process,
681
+ hash it, and put the digest next to the object in the reply. One trip. A
682
+ describe that throws or falls silent costs the digest and nothing else.
683
+ On the empty ask the reply carries no digest; her side hashes what came.
684
+ 6. Answer by the same call the ask came in on.
685
+
686
+ A stranger is bytes the ward cannot admit, and every way of being one is
687
+ listed, with a number, under "Silence, unreached, error". The public being
688
+ is the one door a stranger may walk through, and only because she chose it.
689
+
690
+ ### Inner and outer
691
+
692
+ Inner: being keys, ids, cells, stances, doors, the bind table, every secret,
693
+ every method, every arg, every answer. Nothing inner is ever readable in the
694
+ bytes, and `test/ward.test.ts` reads every byte string that crossed to check.
695
+
696
+ Outer: ward pks, heir pks, ephemeral pks, ciphertext. That is the whole of
697
+ what the wire sees. The one value a being holds that is outer is the
698
+ invitation, which she carries opaque and never opens.
699
+
700
+ A far ward binds a heir to a pk, never to a being. Two far beings that talk
701
+ to two beings of mine see two heirs and one ward pk, and two relations that
702
+ share no key learn nothing from each other.
703
+
704
+ ### The wire
705
+
706
+ Four algorithms, named once and never negotiated: Ed25519 signs, X25519
707
+ agrees, SHA-256 hashes, AES-256-GCM encrypts with key and nonce derived
708
+ together by HKDF-SHA-256 under an empty salt and the label `quo-seal`. The
709
+ ephemeral pk is the additional authenticated data of every box. A small-order
710
+ public key verifies nothing; an all-zero agreement is refused. All four are
711
+ in WebCrypto, which is why the ward names no package -- on any terrain that
712
+ carries them. SHA-256, AES-GCM and HKDF are everywhere; the two curves are
713
+ recent, and a terrain without them is a terrain no ward runs on. The floor is
714
+ named and probed in `test/floor.test.ts`. `crypto.subtle` is read at every use
715
+ and never captured at load, so a page without one -- a plain http:// origin, a
716
+ sandboxed frame -- fails at the first ask with one sentence rather than deep
717
+ inside a key import. The arithmetic is `src/ward/arithmetic.ts`, the seal is
718
+ `src/ward/seal.ts`, and `vectors/arithmetic.json` and `vectors/framing.json`
719
+ hold fixed inputs and outputs so a kit in another language proves it agrees
720
+ on the bytes.
721
+
722
+ ```
723
+ ask on the wire box = ephemeral X25519 pk (32) || AES-GCM( payload || signature (64) )
724
+ sealed to the ward padlock. nothing rides outside it.
725
+ payload = JSON { to, by, next, seq, time, hops?, method?, args }
726
+ signed by `by`. to, by, next: 64 hex. to, next may be null.
727
+ to names the heir, or null for the public being.
728
+ hops is reserved: a whole number, never below zero,
729
+ refused at zero, and nothing sets it.
730
+ reply on the wire box = ephemeral X25519 pk (32) || AES-GCM( reply || signature (64) )
731
+ sealed to the ask's ephemeral pk, signed by the ward key
732
+ reply = JSON { object, seen } | { silence: true }
733
+ ```
734
+
735
+ Nothing rides outside the box, and `to` is the reason to say so. A heir is
736
+ the one name in a relation that never rotates, while the keys under it
737
+ rotate on every ask. Outside the box it would be a handle on that relation
738
+ that never changes: an intermediary carrying the bytes could tell one
739
+ relation from another and follow it for as long as it lasts, and so could
740
+ anyone who ever saw the invitation, which carries that same heir. What
741
+ carries an ask to a ward is the ward pk, which a harbor holds itself and
742
+ never reads from these bytes, so the door loses nothing by opening every ask
743
+ with its own padlock and reading `to` after. What an intermediary still
744
+ learns is the ward it is carrying to, and that is the price of being
745
+ reachable.
746
+
747
+ The sender keeps the ephemeral secret of the box until the reply comes and
748
+ opens the reply with it. A reply that does not open, or is not signed by the
749
+ ward it was sent to, is silence. Unreached never crosses: the wire's nothing
750
+ is it.
751
+
752
+ ## The ward
753
+
754
+ ### What a ward is
755
+
756
+ One process of its harbor. A being plus ward functions. It has one voice, the
757
+ door, and every arrival at that door is judged by it and named by it or falls
758
+ silent. It keeps every being it booted, builds every stance, mints every
759
+ key, seals every ask that leaves, and unseals every one that arrives. Its
760
+ beings trust it blindly. It trusts its harbor the same way.
761
+
762
+ Its ward is itself. It boots itself as the first being in its own map, under
763
+ its own pk, and its own stance is built by the same code that builds every
764
+ being's. Its cells are its partition, all the way down.
765
+
766
+ It owns nothing durable. It is three things, all in the harbor's hands:
767
+ its seed, its partition, and the classes its beings are made of. The
768
+ partition names each class and the harbor holds the bodies, so a ward is
769
+ whole only where all three are, and a harbor that keeps one remembers where
770
+ the other two came from. It writes as it runs and never decides, asks, or
771
+ learns whether anything was kept. Between one run and the next, a ward is
772
+ nothing at all.
773
+
774
+ One ward is one runtime and one language, and every being in it shares both.
775
+ A harbor that wants two languages starts two wards at least. Under
776
+ `src/being/`, `src/ward/`, `src/harbor/` and `src/conformance/` no runtime is
777
+ named. The whole
778
+ platform surface is the language plus six globals -- `crypto`, `TextEncoder`,
779
+ `TextDecoder`, `structuredClone`, `setTimeout`, `atob` -- and that list is a
780
+ promise, not an accident: `test/terrain.test.ts` fails the build both when a
781
+ file names a platform and when it reaches for a global outside the list.
782
+
783
+ The package exports raw TypeScript, extension and all, on every specifier, so
784
+ Node loads it directly and every other terrain reaches a ward through a
785
+ bundler. `test/bundle.test.ts` bundles the three words and runs them, and
786
+ asserts the artefact carries nothing a terrain cannot provide.
787
+
788
+ The conformance suite is the ward's truth, so it has to be checkable wherever
789
+ a ward runs. It names no runtime either: its runner is handed in, and the five
790
+ assertions it makes are `src/conformance/assert.ts`, held to
791
+ `node:assert/strict`'s own behaviour by `test/assert.test.ts`.
792
+ `test/terrain/exercise.ts` is what every terrain runs -- the whole suite,
793
+ under all three topologies, and the floor probe. Node is the reference: no
794
+ terrain carries a count of its own, so a test added to the suite is demanded
795
+ of every terrain at once. Five run it: Node, a browser, workerd, Deno and
796
+ Bun. Bun is the one that is not V8, so "the language alone" is checked
797
+ against two implementations of the language and not one.
798
+
799
+ `npm run check` is Node alone, and stays fast. `npm run check:terrain` is the
800
+ browser and the edge, kept apart because a browser is a download and not a
801
+ package: a fresh clone needs `npx playwright install chromium` first, and is
802
+ told so in one sentence rather than a stack trace.
803
+
804
+ ### The partition
805
+
806
+ Everything durable a ward has is here, every secret included, and nothing
807
+ here is ever in a being's cells. Values only, so the harbor may persist it as
808
+ it likes: as this process's objects, as a row, as a line of JSON on a disk. A
809
+ reboot from its JSON is the same ward. The shape is `src/ward/partition.ts`.
810
+
811
+ ```
812
+ partition
813
+ version 'pre-1.0.0'
814
+ beings key -> her cells, with class
815
+ bind key -> her bind table
816
+ standings id -> { ward, heir | null, current, next, seq } her keys for a standing
817
+ occupants id -> heir pk
818
+ knocks <ward>:<heir> | public:<ward> -> { current, next, spoke, seq } before take
819
+ answered <ward>:<heir> | public:<ward> -> true knocked and answered
820
+ minted the last eight pks her side minted
821
+ heirs heir pk -> { being, id, current, announced, fresh, mark, spent } the door's view of every occupant
822
+ public the one public being's key, or null
823
+ ```
824
+
825
+ A knock record is filed under the ward and the heir together, never the heir
826
+ alone: an invitation carries the heir to whoever it is for, and anyone
827
+ holding one could quote that heir back inside an invitation naming a ward of
828
+ their own.
829
+
830
+ The version is one value and it does not move until 1.0.0. There is nobody
831
+ holding a partition of another shape to tell apart: if the shape changes, a
832
+ partition is thrown away, not migrated and not counted. A ward opening a
833
+ version it cannot read throws at birth and does not boot. Birth is where a
834
+ ward is allowed to be loud; silence is the door's word, for asks that were
835
+ made, and no ask has been made yet.
836
+
837
+ What a ward can read is a list, `READS`, and today it has one member. The
838
+ list and the step that carries an older partition forward exist before
839
+ 1.0.0 because after it there is nowhere to put them. A partition holds every
840
+ secret and every relation a world has: the first shape change after the
841
+ freeze cannot be answered by throwing it away, and a ward that meets a shape
842
+ it has no step for refuses to boot with all of it still inside. Throwing a
843
+ partition away is what a version means before 1.0.0, and carrying it forward
844
+ is what it means after; the seam is cut now so the second is possible.
845
+
846
+ ### Restart
847
+
848
+ A restart is silent because the ward cannot tell rebirth from birth. Every
849
+ being whose cells record a class is constructed again, unasked, with the
850
+ same cells; relations and keys are intact on both sides; a knock answered
851
+ before the restart can be taken after it; a door that restarts still refuses
852
+ what it already honoured.
853
+
854
+ A constructor that throws on a restart takes only herself down: she is
855
+ absent this run, no door, so silence at her door, and her cells sit untouched
856
+ waiting for the run that can read them. The ward is up and so is everyone
857
+ else. A class the harbor no longer knows is the same absence, and so is a
858
+ class the harbor holds at a body the cells were not written for: which body
859
+ a ward reboots on is the harbor's decision, and a ward cannot tell an old
860
+ one from a new one. Loss of the partition is loss of every relation,
861
+ announced to nobody.
862
+
863
+ ### The owner
864
+
865
+ The owner is a role, not an identity, and it has a root. The root owner is
866
+ whoever holds the ward's ask pointer. The harbor hands that pointer to one
867
+ holder, by the device's rules: a shell, a UI, a socket only the device's
868
+ user can read. Lose the pointer, lose the root; there is no recovery inside
869
+ Quo.
870
+
871
+ Every other owner is an occupant of the ward itself. The ward is a being of
872
+ its own map, and the root may invite on it like on any being; whoever knocks
873
+ with that invitation is an owner, reached through the door, named by the id
874
+ the root chose, counted and rotated like any relation, and removed like any
875
+ occupant. That is how a ward is piloted from another device: the piloting
876
+ ward holds a standing at it, and every owner ask is a sealed ask. Only the
877
+ root may invite on the ward: an owner at the door asking to is refused, so
878
+ a carried key pilots and never hands piloting on. Ownership moves by the
879
+ root inviting one owner and removing another, and a migrated ward carries
880
+ its owners in its bind table, so the harbor that receives it does not
881
+ become one.
882
+
883
+ The root is not an occupant. It holds no heir, no key, no invitation. The
884
+ ward names every arrival on the ask `{ id: 'OWNER' }`, the third asker of the
885
+ 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, place a
887
+ relation into a being of the ward, and take one out of her. The root's asks
888
+ carry no allowance of their own.
889
+
890
+ ```
891
+ ask() -> { asks: [boot, invite, knock, remove],
892
+ notes: { pk, beings: { key: { class, public, digest } } } }
893
+ ask('boot', { key, class, public? }) -> { booted: key } | { error }
894
+ ask('invite', { being, id }) -> invitation | null | { error }
895
+ ask('knock', { being | { boot: class, key },
896
+ id, invitation, method?, args?, wanted? })
897
+ -> { taken: id | null, answer } | { error: 'silence' | 'unreached' | ... }
898
+ ask('remove', { being, id }) -> { removed: id } | { error }
899
+ anything else -> { error: 'unknown ask' }
900
+ ```
901
+
902
+ - The owner is a caller like any other: `wanted` says what its knock may
903
+ spend, and saying nothing is the ward's default, exactly as for a being.
904
+ - The describe runs every being's own describe as `OWNER` and hashes it; a
905
+ being that throws or falls silent there shows a null digest.
906
+ - Boot refuses a key already booted, a class the harbor does not know, and a
907
+ second public being; a boot that made nobody leaves the partition as it
908
+ found it. A throw at birth is that boot's error, and nothing half-lives.
909
+ - Invite on the ward's own pk mints an owner, and only the root may ask it:
910
+ from the door it is answered as an invite on nobody. The ward has
911
+ occupants, its owners, and no standings: a knock for the ward itself is a
912
+ knock for nobody, because the ward asks nobody anything.
913
+ - The owner's knock is a being's knock made for her. The ward knocks under a
914
+ key it mints for her, and if answered, takes under the id the owner gave
915
+ and writes the standing into her cells. She finds it there. Her owner
916
+ chose her class and her cells at boot; her owner may choose a relation for
917
+ her too. The boot form names a being new or existing: a key already booted
918
+ is a being of theirs, not a class that failed.
919
+ - The owner's remove is the mirror of its knock: a relation out of a being,
920
+ by id, and the id may be an occupant or a standing, since the two share
921
+ one namespace. The being's own remove says nothing; the owner hears
922
+ objects, so this one says what it removed, and that there was nothing when
923
+ there was nothing. Remove on the ward's own pk unseats an owner, and only
924
+ the root may ask it, for the reason only the root may invite one: from the
925
+ door it is answered as a remove on nobody. Ownership moves by the root
926
+ alone.
927
+
928
+ The door is a ward function. It is not the ward's answer: it judges before
929
+ anything is named, and a being's answer only ever receives named askers. The
930
+ ask is the ward's answer, with the asker filled in as owner. Ward functions
931
+ are on the object, and no stance and no standing reaches them.
932
+
933
+ ### Responsibilities, and not
934
+
935
+ The ward:
936
+
937
+ - Derives its pk from its seed and names itself outward by that and nothing
938
+ else. Mints every other key from the ground's random, one per side of one
939
+ relation.
940
+ - Instantiates beings when the owner asks, by class name. It builds the
941
+ stance, names the class, and receives the object from the harbor's
942
+ instantiate call. It never sees a class body, its own included.
943
+ - Keeps, per being, the cells, the standings and the occupants, in the
944
+ partition, and outside her cells the bind table. Never reads notes.
945
+ - Mints a heir for every id a being mints, keeps its pk beside the id, and
946
+ hands her the invitation. Names every arrival signed by the key it holds
947
+ for that heir by the id she minted.
948
+ - Seals every ask that leaves to the far ward's padlock, signed by the
949
+ standing's own key, announcing its next, carrying its count and its
950
+ allowance. Delivers to its own pk without the harbor. Hands every other
951
+ ward pk to carry. Bounds the wait.
952
+ - Tells its own being the truth about her asks: an answer with its digest
953
+ written to seen, silence when bytes came back and said nothing, unreached
954
+ when nothing came back.
955
+ - Runs her answers concurrently and never serializes her. Two different asks
956
+ may both be inside her answer at once, one paused, one running. Her cells
957
+ are hers to guard between one line and the next.
958
+
959
+ Not stressed with:
960
+
961
+ - Where any pk lives. Sockets, URLs, DNS, containers, planets. It knows pks
962
+ and nothing under them. The wire, retries, or the directory.
963
+ - Storage. It writes into its partition and does not know what medium that
964
+ is, whether it persists, or when.
965
+ - Defending against its harbor. A ward that distrusts its harbor has no
966
+ move, so Quo gives it none. The harbor vouches, the ward trusts. A being
967
+ trusts her ward, a ward trusts its harbor, a harbor trusts its device. A
968
+ broken vouch is total and silent.
969
+ - Deciding who may be an occupant. She invites; it binds and names.
970
+ - Restarting a crashed being, retrying a silent ask, or noticing that a
971
+ standing walked away. A being learns about a standing by asking it, and
972
+ from nothing else. There is no estate. The far being is sovereign: she may
973
+ fall silent on the ask after the knock, and nobody is told.
974
+ - Blacklists, rate limits, and what to do with a pk that keeps knocking with
975
+ garbage. Its own.
976
+
977
+ ## The harbor
978
+
979
+ A harbor is what a device already has, offered to Quo: processes, storage, a
980
+ network, entropy, a clock. It fits into a device carved up by its owner,
981
+ users, containers, mounts, profiles, and asks for none of them. It knows no
982
+ being, holds no id, reads no partition, and is nobody outside its device.
983
+
984
+ The harbor:
985
+
986
+ - Boots wards as processes, one seed each, and keeps each ward's partition.
987
+ - Holds the class bodies for its wards, and remembers for each ward where
988
+ its bodies came from, so that a restart is on the same bodies unless the
989
+ harbor decides otherwise. Constructs a being when a ward names a class
990
+ through the ground's instantiate, and never chooses a class itself. A
991
+ name it does not hold is null, and that boot fails. Whose code a ward
992
+ runs is no concern of the harbor: a ward of its owner's and a ward whose
993
+ bodies came from a stranger are hosted the same way.
994
+ - Passes every ward the ground, once, at birth. Receives a door and an ask.
995
+ Hands the ask to exactly one holder, by the device's own rules. That
996
+ holder is the ward's owner.
997
+ - Keeps the map of ward pk to door for its own wards, and ward pk to reach
998
+ for foreign ones. Learns its own wards' pks by asking them. Learns foreign
999
+ pks however it likes.
1000
+ - Carries bytes to one ward pk and returns what came back, or nothing.
1001
+ Copies bytes across, never references, even between two of its own
1002
+ doors. Nothing means the bytes never arrived: no reach for that pk, a
1003
+ socket that would not open, a link that is down. Once it has sent them it
1004
+ never answers nothing on its own patience; it waits, and the ward's bound
1005
+ ends the ask.
1006
+ - Receives bytes from the wire for a ward pk it holds, hands them to that
1007
+ one door, and returns what the door returned.
1008
+ - Vouches: the seed stays secret, the partition is reached by this ward
1009
+ alone, the ask reaches its root owner alone, the device is the harbor's
1010
+ to defend. How is the device's business. Custody is this vouch: two
1011
+ harbors booting one seed over one partition are two wards with one pk,
1012
+ diverging in silence, and a harbor refuses to boot a ward another running
1013
+ harbor holds, by whatever lease its device offers.
1014
+
1015
+ Not stressed with:
1016
+
1017
+ - Reading, altering, caching, or retrying bytes. It does not know the word
1018
+ silence, and it never answers on a ward's behalf.
1019
+ - Fanning out, broadcasting, or forwarding to a pk other than the one it was
1020
+ given. One pk is one ward is one door.
1021
+ - Beings, ids, keys inside a relation, classes as things to choose,
1022
+ invitations, or what any partition contains.
1023
+ - Judging anything. A ward judges its door. The harbor delivers to it.
1024
+ - Speaking Quo. It is nobody's occupant and holds no standing anywhere. The
1025
+ harbor is not a ward and is nobody's.
1026
+
1027
+ The memory harbor, `src/harbor/memory.ts`, is one process and no wire. It
1028
+ keeps partitions by seed, routes its own doors, and may be linked to peers,
1029
+ which stands in for a wire, and cut, which stands in for weather. It routes
1030
+ one hop: a pk that is not its own and not a direct peer's is nothing. It
1031
+ keeps no lease: two of them may hold one seed and one partition, which is
1032
+ the broken vouch every real harbor refuses, kept here so that the tests can
1033
+ show what divergence looks like. Every ward and being assertion in the tree
1034
+ is made on it, so that the network never hides a fault in the words.
1035
+
1036
+ What a harbor on a device keeps is a ward's three parts under one name: the
1037
+ seed, the partition, and a **ward record**, which says where the class
1038
+ bodies come from and which being is the user's. That is the **store**,
1039
+ `src/harbor/store.ts`: list, load, put, save the partition after a call,
1040
+ save the record after a boot learned the pk, take a ward out as the first
1041
+ move of a migration, and keep the directory's hints, a pk to a URL, across
1042
+ a restart. A name already kept is refused. A store reads nothing it keeps
1043
+ and hands the partition back as values, never as the object it was given.
1044
+ The memory store beside the interface is the library's own; a disk, a tab
1045
+ and an edge object each have theirs, outside this tree, and every one of
1046
+ them passes `src/conformance/store.ts` untouched.
1047
+
1048
+ Carrying bytes to a pk off the device is a **reach**, `src/harbor/reach.ts`:
1049
+ carry bytes to a pk, get bytes back or nothing. Two kinds, and no third:
1050
+ a **request**, one URL, the bytes posted to it with the pk as the last
1051
+ segment and the reply as the answer, listener to listener; and a
1052
+ **socket**, one held line used in
1053
+ both directions, opened by whichever side can dial, with a frame id
1054
+ matching each reply to its ask and one text frame in which a side announces
1055
+ the ward pks it holds. The framing on a socket is binary: an ask is a kind
1056
+ byte, a four-byte id, the 64-byte pk and the bytes; a reply is the kind, the
1057
+ id and the bytes; and nothing delivered is the kind and the id alone. Both
1058
+ kinds are written on the standard surface every terrain carries, fetch and
1059
+ WebSocket, and this tree holds either end of a line and never a listener:
1060
+ who accepts a socket is the terrain's business. A reach reads nothing.
1061
+ Nothing comes back only where the reach knows nothing was delivered: no such
1062
+ pk at the far end, a connection that would not open, a line already gone. A
1063
+ reach that sent the bytes and lost the line after answers nothing at all,
1064
+ and the ward's bound ends the ask. Every reach passes
1065
+ `src/conformance/reach.ts` untouched, and the frames are pinned in
1066
+ `vectors/wire.json`.
1067
+
1068
+ A reach also carries the **wire suite**: which frames these are, and which
1069
+ four algorithms seal what they travel with. It is one number, it is not
1070
+ negotiated, and today it is 1. It rides where a line is opened and never on
1071
+ an ask: in the text frame a socket announces itself with, and as the header
1072
+ `quo-suite` on a request. So an ask is still bytes from the first one, with
1073
+ nothing in front of them to say what they are, and a line still learns
1074
+ before it carries anything whether the far side speaks what this side
1075
+ speaks. A side meeting a suite it does not know carries nothing for it and
1076
+ closes, naming the refusal on the way out with close code 4001; a
1077
+ request door meeting one answers nothing delivered. A dialer refused that
1078
+ way waits out the ceiling before asking again, because a suite does not
1079
+ become speakable by asking sooner. Its wait returns to the first second
1080
+ where the far side announced and was taken, and not where the line merely
1081
+ opened: a listener that opens and then refuses would otherwise be dialed at
1082
+ a fixed two seconds for good, which is what the lab measured before the
1083
+ code was read. Absent is this suite,
1084
+ because a caller older than the header is this one. Present and different is
1085
+ refused as it is written: the number is compared as it was sent, so a suite
1086
+ is one spelling and not a family of them.
1087
+
1088
+ This is the only place a second suite could ever be told from the first.
1089
+ The four algorithms are named once and never negotiated, which is right: a
1090
+ choice offered on the wire is a choice a stranger can push. But named once
1091
+ is not the same as unnameable, and a kit that must one day seal differently
1092
+ has to be able to say so to a kit that cannot, or the day it arrives every
1093
+ world stops answering at once and none of them can say why. A silence names
1094
+ no reason, by law. This number is the reason, said before the silence.
1095
+
1096
+ The **harbor core**, `src/harbor/core.ts`, is what every harbor on a device
1097
+ is: the store and the reach put together under the ground. It boots every
1098
+ ward the store keeps, keeps the map of ward pk to door for its own wards
1099
+ and the **directory**, pk to reach, for foreign ones, carries bytes to a
1100
+ pk and delivers bytes from the wire to one door. The directory is filled
1101
+ three ways, in this order: its own doors; a socket a dialer holds to it,
1102
+ bound at the dialer's announce and unbound when the line closes; and a
1103
+ hint, a pk at a URL, kept in the store. One rule makes a **rendezvous** of
1104
+ any listener: bytes that arrive from the wire go to an own door or to a
1105
+ socket this harbor holds for that pk, and never onward by request. So a
1106
+ harbor that cannot be dialed is reached through the one it dialed, by
1107
+ anyone who holds a hint that its pk is there. The **dialer**,
1108
+ `src/harbor/dial.ts`, is that harbor's half: one held socket to a URL, its
1109
+ own pks announced when the line opens, the listener's bound, dialed again
1110
+ with a wait that doubles from a second to thirty when the line drops, and
1111
+ while it is dialed it is one of the harbor's fallbacks, where a pk nobody
1112
+ here knows is sent. Fallbacks are a list and a pk is tried down it in
1113
+ order: a harbor may dial more than one listener, and a rendezvous is a
1114
+ listener and nothing more, so a ward is never reachable through one place
1115
+ by anything but its own choice. A line that drops takes only its own place
1116
+ out of the list. A ward is born on the core by minting a seed under a name,
1117
+ leaves it by being dropped, the partition written first, and arrives by
1118
+ being adopted, same seed, same pk. What a terrain adds is a store of its
1119
+ own, a loader for the class bodies, and the lease its device offers; what
1120
+ it never touches is a ward.
1121
+
1122
+ ## The being
1123
+
1124
+ ### What a being is
1125
+
1126
+ One ordinary object, in one language, with one voice. She has state, she can
1127
+ ask other beings, and other beings can ask her. She does not know where any
1128
+ of them are, and she cannot find out. She never touches a key, a wire, or a
1129
+ class. Her ward does all of that, and she trusts it blindly: what the ward
1130
+ names is true.
1131
+
1132
+ She asks her standings by method and args and gets back an object, silence,
1133
+ or unreached. She invites whom she wants, in her own time, and removes them
1134
+ when she decides. She knocks with invitations she was given and takes the
1135
+ ones she wants. She answers every ask her ward brings her with an object or
1136
+ silence; an error is an ordinary object, and she never throws outward. She
1137
+ describes herself, per asker, by answering the empty ask.
1138
+
1139
+ Not stressed with: where anyone lives; crypto, keys, wire, storage, clocks,
1140
+ or the harbor; strangers, because nobody her ward cannot name reaches her;
1141
+ whether an occupant is a person, a model or a program; making beings, because
1142
+ only the ward instantiates.
1143
+
1144
+ ### Her obligations
1145
+
1146
+ 1. Args are one object. A throw is silence outside: the ward is in the
1147
+ middle of every call and catches, always, in every language. An error is
1148
+ an object her output schema declares.
1149
+ 2. No lifecycle. Construction with the stance is birth. A restart is silent.
1150
+ 3. The empty ask is hers. Who gets what blueprint is her decision. She obeys
1151
+ the shape, never a content. The empty ask must be safe to repeat: her
1152
+ ward may ask it at any time, and it changes nothing. Nobody enforces
1153
+ this, in any language. It is her obligation alone.
1154
+ 4. A standing's digest arrives with every answer, as seen. She compares it
1155
+ to digest and refreshes by the empty ask if she wants. The digest is of
1156
+ what she told you, not of who she is: one being, many askers, many
1157
+ digests, all true.
1158
+ 5. An occupant has no digest. She can only be observed, never asked. To
1159
+ reach an occupant, hold a standing at her: she gave you one, or she did
1160
+ not.
1161
+ 6. Her cells are hers to guard between one line and the next. Quo does not
1162
+ serialize her, because that would narrow what can be built.
1163
+ 7. A call is delivered once. Her ward, and the far ward, never let the same
1164
+ call reach a being twice by accident. A repeat is intentional. What she
1165
+ asks is always a new call. The one exception is the public being, who is
1166
+ reached with no heir and no count: the same bytes reach her twice, and
1167
+ her answer must be safe to repeat.
1168
+ 8. Beings do not make beings. A being that could create would hold class,
1169
+ memory and key, and there would be no ward. A being that wants a child
1170
+ gets one from outside, as an invitation handed to her.
1171
+ 9. Whatever her ward cannot name is not hers to worry about: what the ward
1172
+ does with an arrival it cannot name is the ward's.
1173
+
1174
+ ### The base class, and the raw shape
1175
+
1176
+ A being is anything with a constructor taking the stance and an `answer`.
1177
+ The raw shape needs no import from the kit. The kit also offers a base class,
1178
+ `Being` in `src/being/being.ts`, which is a convenience and not Quo:
1179
+
1180
+ - `static cells` are her defaults, merged at birth only where a key is
1181
+ missing, so a restart keeps what she wrote.
1182
+ - `static asks` declares what she can be asked, name to
1183
+ `{ description?, input?, output?, for? }`, in blueprint order.
1184
+ `for(occupant, asker)` decides whether this asker sees the ask, and so
1185
+ whether this asker may call it: what she shows is what she can be asked,
1186
+ one gate for describe and for dispatch.
1187
+ - `answer` is written for her. The empty ask is `describe(asker)`, which she
1188
+ may override by hand. A named ask calls the method of that name with
1189
+ `(args, asker)`. Anything not declared, hidden from this asker, or
1190
+ inherited from Object's prototype is `{ error: 'unknown ask' }` and the
1191
+ method is never entered.
1192
+ - A declared ask with no method, or one named after the base's own members,
1193
+ fails at birth, loudly, so a boot fails and nothing half-lives.
1194
+ - `occupant(asker)` is the occupant record for whoever is at the door, and
1195
+ undefined at a public being. `invite`, `knock`, `take`, `standings` and
1196
+ `occupants` reach the stance and nothing else.
1197
+
1198
+ ### Examples
1199
+
1200
+ The smallest being. Answers whoever her ward names, describes one ask.
1201
+
1202
+ ```js
1203
+ class Echo {
1204
+ constructor(stance) {
1205
+ this.s = stance;
1206
+ }
1207
+ answer(asker, method, args) {
1208
+ if (method === undefined) return { asks: [{ name: 'echo', input: {} }], notes: {} };
1209
+ return { from: asker.id ?? null, ...args };
1210
+ }
1211
+ }
1212
+ ```
1213
+
1214
+ A shop. Invites in her own time, hands the invitation out by any channel,
1215
+ and takes a guest back only if the guest offers a way.
1216
+
1217
+ ```js
1218
+ class Shop {
1219
+ constructor(stance) {
1220
+ this.s = stance;
1221
+ }
1222
+ async invite(name) {
1223
+ const id = `g-${name}`;
1224
+ const inv = await this.s.occupants.invite(id);
1225
+ this.s.cells.occupants[id].notes.expireAt = 2028; // hers, not Quo's
1226
+ return inv; // goes by mail
1227
+ }
1228
+ async answer(asker, method, args) {
1229
+ if (method === undefined) return { asks: [{ name: 'hello', input: {} }], notes: {} };
1230
+ const rec = this.s.cells.occupants[asker.id];
1231
+ if (method === 'hello' && args.invitation) {
1232
+ const back = await this.s.standings.knock(args.invitation, 'hi');
1233
+ if (back !== silence && !isUnreached(back))
1234
+ await this.s.standings.take(`back-${asker.id}`, args.invitation);
1235
+ }
1236
+ return { welcome: rec.notes.expireAt > 2026 };
1237
+ }
1238
+ }
1239
+ ```
1240
+
1241
+ A guest. Consumes an invitation, and only then decides to keep the shop.
1242
+
1243
+ ```js
1244
+ class Guest {
1245
+ constructor(stance) {
1246
+ this.s = stance;
1247
+ }
1248
+ async join(invitation) {
1249
+ const mine = await this.s.occupants.invite('shop'); // so the shop can reach me
1250
+ const out = await this.s.standings.knock(invitation, 'hello', { invitation: mine });
1251
+ if (out === silence || isUnreached(out)) return out; // nothing was born
1252
+ await this.s.standings.take('shop', invitation); // now, and only now
1253
+ return out;
1254
+ }
1255
+ answer(asker, method) {
1256
+ if (method === undefined) return { asks: [{ name: 'hi', input: {} }], notes: {} };
1257
+ return { heard: method };
1258
+ }
1259
+ }
1260
+ ```
1261
+
1262
+ A relay. Forwards every ask to one standing and never looks inside, and asks
1263
+ for a short wait because she is one door of several.
1264
+
1265
+ ```js
1266
+ class Relay {
1267
+ constructor(stance) {
1268
+ this.s = stance;
1269
+ }
1270
+ answer(asker, method, args) {
1271
+ return this.s.standings.next.ask(method, args, { time: 2000 }); // silence and unreached pass through
1272
+ }
1273
+ }
1274
+ ```
1275
+
1276
+ A watcher. Notices a standing changed shape, then decides.
1277
+
1278
+ ```js
1279
+ class Watcher {
1280
+ constructor(stance) {
1281
+ this.s = stance;
1282
+ }
1283
+ async answer(asker, method, args) {
1284
+ if (method === undefined) return { asks: [{ name: 'poke', input: {} }], notes: {} };
1285
+ const out = await this.s.standings.src.ask('read', args);
1286
+ const rec = this.s.cells.standings.src;
1287
+ if (rec.seen !== rec.digest) {
1288
+ const bp = await this.s.standings.src.ask(); // refresh, or
1289
+ if (!bp?.asks.some((a) => a.name === 'read')) this.s.standings.remove('src'); // walk away
1290
+ }
1291
+ return out;
1292
+ }
1293
+ }
1294
+ ```
1295
+
1296
+ ## The tree
1297
+
1298
+ The repository is one TypeScript implementation of this document, run
1299
+ directly on Node's type stripping, no build step, no dependencies. Node 22.18
1300
+ or later. The package is `@quo-systems/quo`, published from 0.1.0, the
1301
+ first version under this name, and it starts over: nothing before it under
1302
+ any other name is this protocol. Before 1.0.0 every version may change the
1303
+ words, and nothing is kept for a holder of an earlier one. `npm pack
1304
+ --dry-run` shows what ships: the four source folders, the vectors, this
1305
+ document, the README and the licence, and nothing else. This document
1306
+ ships, decided here: it is the truth the source and the vectors are read
1307
+ against, and a kit in another language is written against it and nothing
1308
+ else. Publishing runs both gates first, `npm run check` and
1309
+ `npm run check:terrain`, and refuses on a failure.
1310
+
1311
+ ```
1312
+ src/being/ the Being side. types, the base class, silence, the digest.
1313
+ src/ward/ the ward. door, seal, arithmetic, heirs, stance, owner, partition, cells, allowance.
1314
+ src/harbor/ the Ground contract, the memory harbor, the store, the reach and the harbor core.
1315
+ src/conformance/ the behaviours any ward must show, and the fixed beings they are shown with.
1316
+ test/ the suites.
1317
+ vectors/ fixed inputs and outputs: the arithmetic, Quo's own framing, the frames on the wire.
1318
+ ```
1319
+
1320
+ `estate/` sits beside `src` and is not Quo: the beings, screens, model sides
1321
+ and real harbors built on it, each folder with its own document. This
1322
+ document does not read them, and they may not add a word to it. Its one
1323
+ claim on them is that every harbor there passes `src/conformance/` untouched.
1324
+
1325
+ The hand to a kit in another language is two things, and they are of two
1326
+ kinds. `vectors/` is the byte-level hand: fixed inputs and outputs for
1327
+ everything a stranger can observe, the arithmetic, the ward pk, the digest,
1328
+ the signed body, the sealed shapes, the invitation, the knock, and the
1329
+ frames on a socket and the one request a door takes. A kit reproduces them
1330
+ or it is not this protocol. `src/conformance/` is the behavioural hand, and
1331
+ it is a checklist and not a harness: one ward is one runtime and one
1332
+ language, so the beings it is shown with run only in a TypeScript ward, and
1333
+ a kit ports the suite and its beings and reads them beside its own. Nothing
1334
+ in this tree drives a foreign ward through its door, and nothing is owed
1335
+ here before 1.0.0 that does: the door's thirteen cases and the vectors are
1336
+ what two kits meet on, and the suite is what each proves alone.
1337
+
1338
+ Entry points: `@quo-systems/quo` is the Being side, `@quo-systems/quo/ward`
1339
+ is `Ward`, `@quo-systems/quo/harbor` is `MemoryHarbor`, `Harbor`, the
1340
+ store, the reach and the dialer, and `@quo-systems/quo/conformance` is
1341
+ `conform` with the store and reach suites beside it.
1342
+
1343
+ The gate is `npm run check`: typecheck under TypeScript 7, oxlint with
1344
+ type-aware rules, markdownlint, then every suite under `node --test`. There
1345
+ is no CI; the gate runs in seconds and is run before every commit. Nothing
1346
+ red is committed except a test marked todo, which is a claim the tree does
1347
+ not yet meet and says so.
1348
+
1349
+ ### The suites
1350
+
1351
+ The beings are fixed and the ward is what is tested. A ward kit in any
1352
+ language offers the ground, the door, and the owner's ask as written, and
1353
+ passes the same suite. Those tests are the checklist, not the mock.
1354
+
1355
+ - `test/being.test.ts`: the base class against a stance stub. No ward, no
1356
+ harbor. Defaults, describe, dispatch, the gate, the reserved names, the
1357
+ digest.
1358
+ - `src/conformance/index.ts`: one suite of behaviours, written against the
1359
+ stance and one probe: a kit hands the suite its ward's heir table and
1360
+ bind table as values, and a forged knock, so the suite can see that a
1361
+ refusal wrote nothing and a knock bound what it should. It reads them and
1362
+ never writes them. With the beings in `src/conformance/beings.ts`: a
1363
+ printer, a shop, two customers, one raw being with no base class, and a
1364
+ member of an estate. Any ward must pass it, under any topology.
1365
+ - `src/conformance/estate.ts`: the estate, and the last chapter of that
1366
+ suite. Every other chapter is a scene: three beings, one move, one answer.
1367
+ This one is a graph under churn, which is the shape an organisation running
1368
+ on Quo actually has -- scattered wards on scattered harbors, partners and
1369
+ employees invited, knocking, taken, kicked, and moving to harbors of their
1370
+ own. It keeps a model of the graph, plays legal moves against it from three
1371
+ fixed seeds, and after every move holds three things: that the ledger every
1372
+ ward keeps closes on both ends, that every arc in it answers when asked
1373
+ exactly what being that arc means, and that the same seed played under all
1374
+ three topologies lands on the same graph. The last is the promise of Quo at
1375
+ a scale a scene cannot reach. A relation is two arcs and never one edge:
1376
+ the occupant is the host's, the standing is the guest's, and the model
1377
+ keeps them apart because the ward does. A red run prints its seed and the
1378
+ moves that got there. It is read beside one hand-written story that says in
1379
+ prose what the model is for.
1380
+ - `test/ward.test.ts`: the conformance suite against the real ward under
1381
+ three topologies over the memory harbor, one ward, one harbor with a ward
1382
+ per being, two harbors; and what only a real ward can be asked: the
1383
+ owner's asks, the door judged byte by byte, rotation and a lost reply,
1384
+ replay, a restart, and every byte on the wire inspected for anything inner.
1385
+ - `test/public.test.ts`: the public being, what the door does and does not
1386
+ do for her.
1387
+ - `test/silence.test.ts`: the chapter "Silence, unreached, error" by its
1388
+ numbers: the five silences and two unreacheds of her ward, the thirteen
1389
+ cases of the door with a partition snapshot under each, hops refused at
1390
+ zero, and the six lines of the law of one silence.
1391
+ - `test/blueprint.test.ts`: blueprints and instantiation through a real
1392
+ ward. What a boot leaves behind, what a restart brings back when the code
1393
+ moved under the cells, the gate and the door, the reserved ids.
1394
+ - `test/allowance.test.ts`: the allowance. Default, ceiling, nonsense, the
1395
+ bound, the signed body, the door's refusal, and one ask through a ward.
1396
+ - `test/seal.test.ts`: the arithmetic against `vectors/arithmetic.json`,
1397
+ then the seal, round trip, and what it refuses; then the framing against
1398
+ `vectors/framing.json`. The arithmetic is standard and any language has
1399
+ it. The framing is Quo's own, and a kit that reproduces the hashes and
1400
+ not the ward pk, the digest, the signed ask body, the two sealed shapes,
1401
+ the invitation or the knock is not this protocol. Every seed in that file
1402
+ is fixed, so every output is fixed. The ask body is the payload as JSON
1403
+ and is not canonical: the vectors pin the order the type declares, and a
1404
+ kit that emits another order interoperates, because a door verifies the
1405
+ bytes it received, and will not reproduce the vectors. `hops` is in no
1406
+ vector, because nothing sets it. The invitation is JSON too, and the
1407
+ knock is pinned as the ask it is, by the heir, to the heir, announcing
1408
+ the knocker's own key, and then proven at a real door: a ward booted on
1409
+ the vector's seed, drawing the heir secret as its first entropy, mints
1410
+ the invitation vector, binds the knock vector at its door, answers it,
1411
+ spends the heir, and refuses the same bytes again.
1412
+ - `test/break.test.ts`: adversarial probes. Each states what this document
1413
+ promises, then tries to break it.
1414
+ - `test/gaps.test.ts` and `test/gaps2.test.ts`: cases the memory harbor
1415
+ cannot express because it is honest, in-order and lossless: a lost reply,
1416
+ a cycle, a partition written down and read back, a long relation, one
1417
+ seed booted twice. Each test is a claim that the ward is wrong; one that
1418
+ will not go red is not a bug.
1419
+ - `src/conformance/store.ts`: the store suite, written against the store
1420
+ interface alone and handed a maker of fresh stores. A fresh store keeps
1421
+ nothing; what was put comes back as it went in, as values and not as the
1422
+ object; a name already kept is refused; save and record touch only their
1423
+ part and are nothing on a name not kept; take hands a ward out and frees
1424
+ the name; hints are kept by pk and the last one wins.
1425
+ - `src/conformance/reach.ts`: the reach suite, written against the reach
1426
+ interface alone and handed a far side it controls: a door held behind a
1427
+ pk over there, and the far side dropped. The door's bytes come back;
1428
+ nothing for a pk nobody holds; asks in flight at once each get their own
1429
+ answer; what crosses is a copy both ways; and once the far side is gone,
1430
+ nothing. It cannot assert that a reach which sent and then lost the line
1431
+ answers nothing at all, since a suite cannot wait forever.
1432
+ - `test/harbor.test.ts`: the harbor pieces on the library's own ground,
1433
+ no device and no wire. The store suite against the memory store; the
1434
+ reach suite against the socket framing over two lines in one process, so
1435
+ the frames are asserted with no network under them; the conformance
1436
+ suite against two harbor cores over memory stores reaching each other
1437
+ in-process, drop and adopt as the migration; a restart from the store
1438
+ with the hints; the dialer over a stubbed line, announce, bind, fallback,
1439
+ unbind and the wait before it dials again; and the frames against
1440
+ `vectors/wire.json`, the ask, the reply, nothing delivered and the
1441
+ announce, so a kit reproduces the bytes on a socket; and the request
1442
+ reach against the request record in the same file, over a fetch that
1443
+ sees what a listener would, one POST with the suite in its header, the
1444
+ reply as a 200 and nothing delivered as a 404. A socket to a real
1445
+ listener and every real store pass the same suites outside this tree.
1446
+ - `test/terrain.test.ts`: the terrain census. Nothing under `src/being/`,
1447
+ `src/ward/`, `src/harbor/` or `src/conformance/` names a runtime, and
1448
+ nothing reaches for a global outside the ones it names; nor does the
1449
+ census name one the tree has stopped using. It reads the source as text
1450
+ and not as a parse: it is there to catch drift, and does not pretend to
1451
+ stop someone determined to get around it.
1452
+ - `test/assert.test.ts`: `src/conformance/assert.ts` against
1453
+ `node:assert/strict`, pair by pair. The suite means the same thing on
1454
+ every terrain only if those two agree, so they are compared and not
1455
+ trusted.
1456
+ - `test/floor.test.ts`: the four algorithms this terrain must carry, probed
1457
+ one by one; that the arithmetic spends every one of them; and the two ways
1458
+ a terrain can be short -- no `crypto.subtle` at all, and a subtle without
1459
+ the curves -- each failing at the first call, in one sentence.
1460
+ - `test/bundle.test.ts`: the three words bundled as a consumer must bundle
1461
+ them, the artefact read for anything a terrain cannot provide, and then the
1462
+ whole conformance suite run out of the bundle.
1463
+ - `test/terrain/browser.test.ts`, `test/terrain/edge.test.ts`,
1464
+ `test/terrain/deno.test.ts` and `test/terrain/bun.test.ts`: that same
1465
+ bundle and that same suite in a real Chromium, in workerd, in Deno and in
1466
+ Bun, plus each terrain's floor, and, for the browser, a page whose
1467
+ `crypto` has no `subtle`. Deno runs it a second time with every permission
1468
+ denied but read -- no net, no environment, no write, no subprocess -- which
1469
+ is where a ward that had quietly come to need one of them would fail, and
1470
+ nowhere else in this repository. A terrain whose binary is absent skips and
1471
+ names the command that installs it; it never passes quietly.
1472
+ `test/terrain/engine.ts` runs the bundle in another engine on this machine.
1473
+ Behind `npm run check:terrain`. `test/terrain/bundle.ts` is the
1474
+ bundler and the reference run, `test/terrain/exercise.ts` is what every
1475
+ terrain runs, `test/terrain/floor.ts` is the floor -- each written once, so
1476
+ no terrain can be probed for less than another.
1477
+ - `test/world.ts`: the memory-harbor probe and the three topologies, held
1478
+ apart from any one chapter because every terrain drives the same one. It
1479
+ also answers the two asks the estate needs: the census, which is every
1480
+ partition in the world as values, and a migration, which lifts a partition
1481
+ out of one harbor and boots it from the same seed in the other -- same
1482
+ seed, same pk, so every standing anyone holds still points at her.
1483
+ - `test/repo.test.ts`: this document, the README and the project
1484
+ instructions against the repository: every path they name exists, every
1485
+ source file carries its licence, the package names no host and no user,
1486
+ the awaitable calls are marked and
1487
+ awaited in the examples above, the allowance is decided here and off the
1488
+ Open list, and the allowance is time alone on both sides of the door.
1489
+
1490
+ ### Where the tree stands
1491
+
1492
+ The only place this document may name a gap between itself and the tree.
1493
+ Each line is a debt to close, not a note to keep.
1494
+
1495
+ - **An announce is believed.** A side that opens a socket to a listener and
1496
+ announces a ward pk is bound to it, and nothing asks whether it holds that
1497
+ ward. So anyone who can reach a rendezvous can announce a pk that is not
1498
+ theirs, and asks for that pk are carried to them instead of to the harbor
1499
+ that holds it. They learn nothing by it: what arrives is sealed to a ward
1500
+ key they do not have, and they cannot answer, because a reply is signed by
1501
+ that ward. What they take is reachability, which is the one thing a
1502
+ rendezvous exists to give. Measured on the lab, 2026-09-04. The shape of
1503
+ the answer is a proof at the announce, the ward signing something the
1504
+ listener chose, so that binding a pk needs the key behind it; that is a
1505
+ decision this document has not taken.
1506
+
1507
+ ## Open
1508
+
1509
+ Named, not decided. Nothing is here today: every question this document ever
1510
+ named is decided under Closed, and the slot each one needed is already cut,
1511
+ because a slot costs two lines before 1.0.0 and a partition or a payload
1512
+ shape after it.
1513
+
1514
+ ### Closed
1515
+
1516
+ Decided here, so that the answer is not rediscovered:
1517
+
1518
+ - **Delivered, then died, is refused on repeat.** The far ward receives and
1519
+ crashes, the wire says nothing, and the near ward calls it unreached.
1520
+ Nothing in the kit retries on its own, so a caller who asks again asks
1521
+ under the next number and is heard. A repeated number is refused by every
1522
+ door of this version, D10, and that is the whole answer: a repeated number
1523
+ is only ever seen by the one door it was sent to, so a kit that one day
1524
+ answers it from what the door already said interoperates with one that
1525
+ refuses, the way one ward's ceiling never meets another's. That kit has
1526
+ `last` on the heir to keep the reply in; nothing writes it, and nothing
1527
+ reads it.
1528
+ - **Hops is the door's half, and that half is whole.** An ask carries no
1529
+ count of doors, so a chain of relays is bounded by time alone. `hops` is a
1530
+ field of the ask, a whole number and never below zero, and a door refuses
1531
+ an ask that arrives at zero; nothing sets it and nothing decrements it. It
1532
+ is refused now because a count only bounds a chain if every door on it
1533
+ refuses, and a door written after the count was invented cannot make the
1534
+ doors before it enforce anything. The other half, a being's onward asks
1535
+ inheriting a door's remaining time and a count, needs the ward to know
1536
+ which arrival an onward ask belongs to, and it cannot learn that without
1537
+ naming a runtime. If a relay chain ever needs it, the way in is a field on
1538
+ the stance's `ask`, beside `wanted`, that a being who never sends it never
1539
+ has to know about: an addition on the ward-to-being edge, and no byte on
1540
+ the wire moves.
1541
+ - **An invitation carries no hint.** It is `ward`, and for a heir `heir` and
1542
+ `secret`, and nothing else. Where a ward lives is the harbor's to know and
1543
+ a relation's to not: a hint inside the value would put a route inside a
1544
+ capability that beings hand around opaquely, and it would go stale while
1545
+ the invitation stayed good. A link is the invitation next to a hint, two
1546
+ values travelling together, and the hint goes to the directory while the
1547
+ being receives the invitation as it receives every invitation.
1548
+ - **The owner does not set the allowance default or ceiling.** They are the
1549
+ ward's own policy, never negotiated and never on the wire, and a far door
1550
+ cannot tell one ward's ceiling from another's. A being who wants less than
1551
+ the default says so with `wanted` on the ask, which is the whole of what a
1552
+ being needs. An owner who wants another ceiling is asking for a different
1553
+ ward.
1554
+
1555
+ ## Glossary
1556
+
1557
+ - **being**: one ordinary object with one voice. Asks, answers, decides.
1558
+ - **stance**: the one object her ward hands her at birth. Cells and calls.
1559
+ - **cells**: her state. I-JSON values. Three keys are the ward's.
1560
+ - **standing**: a pointer she holds to another being, through which she asks.
1561
+ - **occupant**: a being she invited, whom her ward names when she asks.
1562
+ - **id**: her own permanent name for one relation. Never crosses the door.
1563
+ - **invitation**: a value her ward makes for an id she minted: its pk, a heir
1564
+ pk, the heir secret. Or a ward pk alone, for its public being. Opaque to
1565
+ her. Travels anywhere.
1566
+ - **heir**: the key her ward mints at invite for one id, and gives away.
1567
+ Names the id outward. Dies the first time it speaks.
1568
+ - **next**: the key a standing announces on every ask, and signs with on the
1569
+ next one.
1570
+ - **count**: the number every ask carries for its relation. Honoured once.
1571
+ - **allowance**: the time an ask may still spend. Inside the seal.
1572
+ - **owner**: the root, whoever holds a ward's unsealed ask; and every
1573
+ occupant of the ward itself, whom only the root invites and only the root
1574
+ removes. A role, not an identity.
1575
+ - **invite**: mint an id and get its invitation.
1576
+ - **knock**: an ask carrying an invitation. Binds the far side to the id.
1577
+ - **take**: keep an answered knock as a standing, under her own id.
1578
+ - **ask**: method and args to a standing. Object, silence, or unreached back.
1579
+ - **answer**: her one function. Object or silence out.
1580
+ - **the empty ask**: ask with no method. Her answer to it is her blueprint.
1581
+ - **blueprint**: her interface as she chooses to show it to one asker.
1582
+ - **digest**: SHA-256 over the JCS of a blueprint. Per relation.
1583
+ - **seen**: the digest her ward last saw arrive with an answer.
1584
+ - **silence**: the far side said nothing. Not retryable blindly.
1585
+ - **unreached**: her ward could not reach the far door. Retryable.
1586
+ - **notes**: hers, inside every occupant record. Quo never reads it.
1587
+ - **partition**: the ward's files. Everything durable, every secret.
1588
+ - **ward record**: what a harbor keeps to boot one ward again: seed,
1589
+ partition, and where its class bodies come from. The harbor's, never
1590
+ the ward's.
1591
+ - **edge**: one of the two seams of Quo, harbor to ward and ward to being.
1592
+ An object crosses once at birth, calls cross for the rest of the ward's
1593
+ life, and nothing else crosses.
1594
+ - **ground**: the one object a harbor passes a ward. Five things.
1595
+ - **door**: the ward's one voice outward. Sealed bytes in, sealed bytes out.