@quo-systems/quo 0.2.9 → 0.2.11

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.
Files changed (78) hide show
  1. package/README.md +19 -10
  2. package/SPEC.md +301 -110
  3. package/dist/being/being.d.ts +2 -2
  4. package/dist/being/being.js +34 -12
  5. package/dist/being/digest.js +26 -8
  6. package/dist/being/index.d.ts +2 -2
  7. package/dist/being/index.js +2 -2
  8. package/dist/being/silence.d.ts +2 -0
  9. package/dist/being/silence.js +12 -0
  10. package/dist/being/types.d.ts +4 -2
  11. package/dist/being/types.js +25 -0
  12. package/dist/conformance/assert.js +40 -6
  13. package/dist/conformance/beings.d.ts +48 -5
  14. package/dist/conformance/beings.js +39 -8
  15. package/dist/conformance/estate.js +110 -21
  16. package/dist/conformance/index.d.ts +5 -2
  17. package/dist/conformance/index.js +165 -7
  18. package/dist/harbor/core.d.ts +5 -2
  19. package/dist/harbor/core.js +195 -45
  20. package/dist/harbor/dial.js +32 -15
  21. package/dist/harbor/index.d.ts +1 -0
  22. package/dist/harbor/index.js +3 -0
  23. package/dist/harbor/memory.d.ts +3 -3
  24. package/dist/harbor/memory.js +7 -12
  25. package/dist/harbor/reach.js +42 -17
  26. package/dist/ward/allowance.js +15 -4
  27. package/dist/ward/arithmetic.d.ts +1 -0
  28. package/dist/ward/arithmetic.js +22 -6
  29. package/dist/ward/cells.d.ts +3 -1
  30. package/dist/ward/cells.js +79 -21
  31. package/dist/ward/door.d.ts +3 -2
  32. package/dist/ward/door.js +38 -10
  33. package/dist/ward/ground.d.ts +5 -1
  34. package/dist/ward/ground.js +38 -1
  35. package/dist/ward/heirs.d.ts +2 -3
  36. package/dist/ward/heirs.js +19 -13
  37. package/dist/ward/index.d.ts +1 -0
  38. package/dist/ward/index.js +3 -0
  39. package/dist/ward/owner.d.ts +6 -27
  40. package/dist/ward/owner.js +59 -33
  41. package/dist/ward/partition.d.ts +3 -0
  42. package/dist/ward/partition.js +109 -4
  43. package/dist/ward/seal.d.ts +1 -0
  44. package/dist/ward/seal.js +41 -13
  45. package/dist/ward/stance.d.ts +7 -3
  46. package/dist/ward/stance.js +156 -66
  47. package/dist/ward/ward.d.ts +10 -0
  48. package/dist/ward/ward.js +123 -51
  49. package/package.json +4 -2
  50. package/src/being/being.ts +33 -11
  51. package/src/being/digest.ts +28 -13
  52. package/src/being/index.ts +2 -2
  53. package/src/being/silence.ts +14 -0
  54. package/src/being/types.ts +39 -5
  55. package/src/conformance/assert.ts +37 -4
  56. package/src/conformance/beings.ts +41 -10
  57. package/src/conformance/estate.ts +107 -20
  58. package/src/conformance/index.ts +188 -13
  59. package/src/harbor/core.ts +203 -46
  60. package/src/harbor/dial.ts +46 -17
  61. package/src/harbor/index.ts +3 -0
  62. package/src/harbor/memory.ts +8 -13
  63. package/src/harbor/reach.ts +47 -21
  64. package/src/ward/allowance.ts +15 -4
  65. package/src/ward/arithmetic.ts +25 -8
  66. package/src/ward/cells.ts +76 -25
  67. package/src/ward/door.ts +38 -12
  68. package/src/ward/ground.ts +52 -3
  69. package/src/ward/heirs.ts +19 -13
  70. package/src/ward/index.ts +3 -0
  71. package/src/ward/owner.ts +65 -46
  72. package/src/ward/partition.ts +109 -5
  73. package/src/ward/seal.ts +41 -12
  74. package/src/ward/stance.ts +163 -64
  75. package/src/ward/ward.ts +124 -52
  76. package/vectors/arithmetic.json +7 -0
  77. package/vectors/framing.json +30 -15
  78. package/vectors/wire.json +4 -4
package/SPEC.md CHANGED
@@ -86,11 +86,20 @@ ground
86
86
  instantiate (class name, stance) -> object | null
87
87
  carry (ward pk, bytes) -> bytes | undefined undefined: no door was reached. a throw is read the same.
88
88
  random (n) -> n bytes of entropy. every key a ward mints is drawn from it.
89
+ wrote () -> nothing. the ward says it after every write to its partition, and nothing else:
90
+ a harbor that keeps the partition saves after it, when it likes and in the order
91
+ it was told. a harbor that keeps nothing leaves it out.
89
92
  ```
90
93
 
91
- Nothing else is ever passed. A harbor that needs a sixth thing has found a
94
+ Nothing else is ever passed. A harbor that needs a seventh thing has found a
92
95
  gap in Quo or a leak into the ward. The shape is `Ground` in
93
- `src/ward/ground.ts`.
96
+ `src/ward/ground.ts`, and beside it are the three pieces every harbor in this
97
+ kit builds one out of: `maker`, the code half, which finds a class by own key
98
+ in the first registry that holds it and remembers the object by the cells;
99
+ `entropy`, the one line every terrain has; and `learnPk`, the empty ask, since
100
+ a harbor learns its ward's pk the way anyone learns anything and has no second
101
+ derivation to keep in step. They are convenience and never contract: a kit
102
+ writes its own harbor, and may write these again.
94
103
 
95
104
  Returned:
96
105
 
@@ -101,7 +110,9 @@ Returned:
101
110
  harbor learns from an arrival, never a reason: a pk that only ever brings
102
111
  strangers' bytes is the harbor's to rate or refuse, and what a bound key
103
112
  hears is sealed to its own lid.
104
- - **The ask.** One call: method and args in, object or silence out.
113
+ - **The ask.** One call: method and args in, a value or silence out. A value,
114
+ not an object: what a being answers is held to the value rule and nothing
115
+ narrower, so a string, a number and an array are all answers.
105
116
  In-process and unsealed. This is the one unsealed ask in Quo, and the only
106
117
  way a ward is piloted. Judgment, catching, and the return table are not
107
118
  skipped: a throw inside is silence, and an unreached shape is silence.
@@ -133,7 +144,7 @@ ever offered, and nothing here may be missing.
133
144
  stance
134
145
  cells her state. values only.
135
146
 
136
- occupants.invite(id) -> invitation | null awaitable: a key is minted
147
+ occupants.invite(id, notes?) -> invitation | null awaitable: a key is minted
137
148
  occupants.remove(id) -> nothing
138
149
 
139
150
  standings.knock(invitation, method?, args?, wanted?) -> object | silence | word
@@ -142,7 +153,8 @@ stance
142
153
  standings[id].ask(method?, args?, wanted?) -> object | silence | word
143
154
  standings.remove(id) -> nothing
144
155
 
145
- boot(class, key) -> key | null a new being of her ward, by class name
156
+ boot(class, key, id?) -> key | null a new being of her ward, by class name.
157
+ with an id, her standing to her under it
146
158
 
147
159
  wanted = { time? } what this one ask may spend, in milliseconds. optional,
148
160
  and so is saying anything at all
@@ -152,7 +164,7 @@ Return table.
152
164
 
153
165
  | call | returns | when |
154
166
  | ------------------- | ---------- | ------------------------------------------------------------------------------------------------------------ |
155
- | invite(id) | invitation | she minted a fresh id; the occupant record exists from now |
167
+ | invite(id, notes?) | invitation | she minted a fresh id; the occupant record exists from now, with those notes on it |
156
168
  | | null | the id already names a record, occupant or standing, or is a reserved word |
157
169
  | remove(id) | nothing | always. removing what is not there is nothing |
158
170
  | knock(inv, m, a, w) | object | the far being answered |
@@ -166,17 +178,25 @@ Return table.
166
178
  | ask(m, a, w) | object | she answered |
167
179
  | | silence | she chose to say nothing, or bytes came back that are not Quo's |
168
180
  | | word | why not: removed, absent, repeated, threw, unreached, late, dropped |
169
- | boot(class, key) | key | she exists from now, with fresh cells, and a restart finds her |
170
- | | null | the key is already booted, the harbor holds no such class, or the class threw at birth |
181
+ | boot(cls, key, id?) | key | she exists from now, with fresh cells, and a restart finds her; with an id, her maker holds her standing |
182
+ | | null | the key is already booted, the harbor holds no such class, the class threw at birth, the id is one the maker |
183
+ | | | already holds or a reserved word, or the relation was refused; nothing of the being made is left |
171
184
 
172
185
  A being may make, and only the owner reaches into another. Boot touches
173
- nobody: the being made has empty cells and no relation, hers included, until
174
- one is invited and taken like any other. What the owner has that she does
175
- not is every ask that reaches into a being from outside: public, invite and
176
- knock for her, remove, unboot. Who may ask her to boot is her gate, as who
177
- may ask her anything is.
178
-
179
- Ask, knock, invite and take are awaitable. Async where the language has it,
186
+ nobody else: the being made has empty cells and no relation but the one her
187
+ maker named, and every other is invited and taken like any other. That one is
188
+ made the way all of them are, and it is the whole of what making gives: the
189
+ being made mints an occupant for her maker under the maker's own key, so she
190
+ knows who made her by that name and by nothing else, and her maker knocks
191
+ with it and takes the standing under the id she gave. Naming no id makes no
192
+ relation at all, and a being made that way is reachable by the owner alone. A
193
+ relation that could not be made is a boot that made nobody: the being made
194
+ goes out again, and nobody saw her, since she is a moment old and named to
195
+ no one yet. What the owner has that the maker does not is every ask that
196
+ reaches into a being from outside: public, invite and knock for her, remove,
197
+ unboot. Who may ask her to boot is her gate, as who may ask her anything is.
198
+
199
+ Ask, knock, invite, take and boot are awaitable. Async where the language has it,
180
200
  blocking where it does not. Every ask she makes is a new call.
181
201
 
182
202
  The asker has three shapes and no fourth, and nothing else ever reaches her.
@@ -281,8 +301,8 @@ S4 the reply is not one bytes came back that do not open, or are n
281
301
  S5 the far door answered silence, or a word, exactly as the door said it.
282
302
  ```
283
303
 
284
- And unreached in two: `U1` the args are not a value, or could not be
285
- sealed, so nothing left;
304
+ And unreached in two: `U1` the args are not one object of values, or could
305
+ not be sealed, so nothing left;
286
306
  `U2` the harbor returned nothing, or threw, so no door was reached. The number is
287
307
  taken all the same, and the gap it leaves in the count is harmless: the door
288
308
  honours any number above its mark.
@@ -302,9 +322,9 @@ strangers: silence, nothing written, heard false
302
322
  D1 the box does not open wrong padlock, garbage, too short. the reply is sealed to the lid if
303
323
  the bytes carried one, and is noise otherwise. a lid that will not
304
324
  take a seal, a small-order point, is no lid: noise.
305
- D2 the payload is malformed by or next not 64 hex, method not a string, args not an object, seq
306
- below one, time not a whole number above zero, hops not a whole
307
- number or at zero.
325
+ D2 the payload is malformed by or next not 64 lowercase hex, method not a string, args present and
326
+ not one object of values, seq not a whole number from one, time not a
327
+ whole number above zero, hops not a whole number or at zero.
308
328
  D3 for nobody, and nobody is home no public being on this ward.
309
329
  D4 for nobody, signature fails the payload names a key it was not signed with.
310
330
  D5 the heir is not held never minted here, and not one she removed either.
@@ -315,12 +335,13 @@ D7 signature fails under an admitted key, or under the key hel
315
335
  refusals to a bound key: a word, nothing written, heard true
316
336
  D8 she is not there `removed`: the occupant record is gone, and this is the key it was
317
337
  bound to when it went. `absent`: the being did not come back this run.
318
- D9 a knock announces nothing `unannounced`: the heir is fresh and next is null. it binds nothing.
338
+ D9 a knock announces nothing `unannounced`: the heir is fresh and next is null, or is the heir
339
+ itself, which is no key of her own. it binds nothing.
319
340
  D10 the number is refused `repeated`: already honoured, or at or below the span.
320
341
  choices: the number spent, the keys rotated, heard true
321
342
  D11 she threw `threw`
322
343
  D12 she answered silence on a named ask, or on the empty ask. nothing at all is silence too.
323
- D13 she answered a word `threw`: a word is not hers to make.
344
+ D13 she answered a non-value `threw`: a word, a Date, a cycle, a NaN, none is hers to make.
324
345
  ```
325
346
 
326
347
  The signature is verified before anything is written and before any word is
@@ -380,7 +401,9 @@ Nothing else is a value: no dates, no references, no functions, no native
380
401
  types. An id or a standing is never a value.
381
402
 
382
403
  Args are held to the same rule before they are sealed: an ask whose args
383
- hold a non-value is unreached, because nothing left. Cells hold values and
404
+ are not one object of values is unreached, because nothing left. Her answer
405
+ is held to it at the door: a shape that is not a value is `threw` to a bound
406
+ key and silence to a stranger, so nothing crosses altered. Cells hold values and
384
407
  refuse anything else at the moment of writing, in her own frame: a Map, a
385
408
  Date, a NaN, a cyclic object, a function, an object that is not a plain one.
386
409
  The refusal is a throw where she wrote it, which her ward turns into the
@@ -399,7 +422,10 @@ None is an object, and none carries anything but its name. In this kit
399
422
  silence is the symbol `quo.silence` and a word is a frozen object under the
400
423
  symbol key `quo.word` holding its name, both from `src/being/silence.ts`;
401
424
  `isWord` and `wordOf` read them, and `isUnreached` is the one word a being
402
- asks about most.
425
+ asks about most. `told` names a word and leaves everything else exactly as it
426
+ came, so asking which word arrived is one comparison rather than two joined by
427
+ an and: `told(out) === 'late'`. A kit in another language spells it however
428
+ that language spells one value standing for either, and owes nothing here.
403
429
 
404
430
  ### Blueprint, schema, digest
405
431
 
@@ -425,6 +451,16 @@ holding what is not a value is dropped before hashing and an array slot
425
451
  holding one is null, which is what crossing an edge does to them anyway. The
426
452
  reference is `src/being/digest.ts`.
427
453
 
454
+ Two places in RFC 8785 are where languages part, and a kit is held to both by
455
+ `vectors/framing.json`. Keys sort by **UTF-16 code unit**, not by code point
456
+ and not by byte, so an astral character sorts before one in the surrogate
457
+ range: `U+1F600` comes before `U+FB33`, which is the reverse of what a
458
+ language sorting code points gives. Numbers are written as ECMAScript writes
459
+ them, `1e+21` and `1e-7` and `0.3333333333333333`, with a negative zero
460
+ written `0`. A kit that reproduces every ASCII vector and neither of these
461
+ hashes one blueprint to two digests, and every standing between the two wards
462
+ refreshes on every ask.
463
+
428
464
  Capability and state are two axes, never mixed.
429
465
 
430
466
  ```
@@ -468,7 +504,12 @@ and take refuse them like the ward's words.
468
504
  ### Cells
469
505
 
470
506
  Cells are I-JSON values. The ward may persist them. A restart is silent: she
471
- is constructed again with the same cells.
507
+ is constructed again with the same cells. Three keys at their root are the
508
+ ward's, `standings`, `occupants` and `class`, and a write of hers to them is
509
+ refused where she wrote it, like a non-value. A value nested past sixty-four
510
+ levels, a hole in a list, an accessor, and a key named `__proto__` are
511
+ refused the same way: JSON writes each one way and a runtime reads it
512
+ another, so no harbor can keep them.
472
513
 
473
514
  ```
474
515
  cells
@@ -479,11 +520,20 @@ cells
479
520
  ```
480
521
 
481
522
  - `digest` is the hash of the blueprint she last fetched by the empty ask.
482
- - `blueprint` is that blueprint.
523
+ It is over what came back, whatever that was.
524
+ - `blueprint` is that blueprint, and only if it is one. A far describe is
525
+ somebody else's code and may answer any value at all; the ward reads it as
526
+ a blueprint before writing it as one, a list of asks with a name and an
527
+ input each, and writes `null` when it is not. A side walks `asks` by name,
528
+ and a side that broke on a far ward's answer would be one kit made wrong
529
+ by another. The answer itself still goes to whoever asked, unread.
483
530
  - `seen` is the digest her ward last saw arrive with an answer. A silent
484
531
  refresh leaves it untouched.
485
532
  - `notes` is hers. Quo never reads it. Tier, expiry, kinship between an
486
- occupant and a standing that are the same far being: all hers.
533
+ occupant and a standing that are the same far being: all hers. `invite`
534
+ may seed it, which is how an inviter says the terms it mints under, and
535
+ after that it is written by nobody but her. The owner's `invite` passes
536
+ what it was given straight through; the ward reads none of it.
487
537
 
488
538
  ## Relations
489
539
 
@@ -543,7 +593,9 @@ and a knock on a taken invitation joins the standing's lane.
543
593
  The keys an ask sends under are read when she calls, not when the lane
544
594
  reaches her: an ask issued while the standing stood is answered even if she
545
595
  drops it in the next line. An ask on a standing she has already dropped is
546
- silence, and so is a knock on the invitation it was born on: after take the
596
+ the word `dropped`, and nothing is sent. A knock on the invitation it was
597
+ born on, after take and a drop, is a knock as a heir the far door has already
598
+ spent, so bytes leave and the door's silence comes back: after take the
547
599
  invitation names the standing and nothing else, so it is exactly as alive as
548
600
  the standing is.
549
601
 
@@ -561,8 +613,22 @@ An invitation to her is `{ ward }` alone. One with a secret and no heir is
561
613
  not an invitation. She may be taken as a standing on that invitation, and
562
614
  such a standing has no heir and never rotates.
563
615
 
616
+ The signature is checked here for no property, and the check is kept anyway.
617
+ Whoever asks chose that key a moment ago, the box is already authenticated to
618
+ the ward's padlock, and the door binds nothing, so nothing is proven by it and
619
+ nothing would be lost by dropping it. It stays because the payload has one
620
+ shape and the door has one path: `by`, `next` and `seq` are required of her
621
+ ask as of every other, and honoured by nobody. A kit author who goes looking
622
+ for the property behind this signature will not find one, and is not missing
623
+ anything.
624
+
564
625
  She is reached without a heir, so the door keeps nothing for whoever asked:
565
- no key it vouched for, and no count. The signature is still checked, under
626
+ no key it vouched for, and no count. The bit beside her reply is `heard`
627
+ false, as it is for every stranger: no key this door holds spoke. She is the
628
+ one place a stranger is answered by design, so she is the one place the
629
+ harbor's rating must still see a stranger arrive. A harbor that saves before
630
+ its reply goes out follows the ward writing, never the bit, since a public
631
+ being writes in her cells like anyone. The signature is still checked, under
566
632
  whatever key signed. Once-only delivery does not reach her: the same sealed
567
633
  bytes presented twice are delivered twice, and the number the payload carries
568
634
  is required and honoured by nobody. A count per voice would be memory a
@@ -614,7 +680,17 @@ key does both: an Ed25519 pair to sign replies, an X25519 padlock every ask
614
680
  is sealed to. Beings never own a padlock.
615
681
 
616
682
  - **The ward key** comes from the seed. Its pk on the wire is the signing pk
617
- then the padlock, 128 hex, and it routes.
683
+ then the padlock, 128 hex, and it routes. Two curves, and each secret is
684
+ HKDF-SHA-256 of the seed under its own label, `quo-ward-sign` and
685
+ `quo-ward-seal`, empty salt, 32 bytes out. Fed the seed straight the two
686
+ scalars would still differ, because Ed25519 hashes what it is given and
687
+ X25519 clamps it raw, but that is an accident of the two designs and no
688
+ separation: one secret would be doing two jobs with nothing said about it,
689
+ and a second kit would have to reproduce a construction nobody named. A
690
+ seed handed in as bytes of the key length is the seed; anything else, text
691
+ or bytes of another length, is SHA-256 first, so a thirty-two character
692
+ name is a name and not a key for being the right size.
693
+ `vectors/framing.json` pins it.
618
694
  - **The heir** is the key the inviting ward mints at invite, for one id. It
619
695
  keeps the heir's pk beside the id and gives the secret away. The
620
696
  invitation IS the heir: ward pk, heir pk, heir secret. Rotation one: the
@@ -622,8 +698,8 @@ is sealed to. Beings never own a padlock.
622
698
  - **Her own key** is what the knocker mints at knock. She signs the knock
623
699
  with the heir and announces her own key in it. The door binds the id to
624
700
  her key and the heir dies as it speaks. Rotation two: from now on she
625
- signs with a key the inviter never held. A knock that announces nothing
626
- binds nothing.
701
+ signs with a key the inviter never held. A knock that announces nothing,
702
+ or announces the heir itself, binds nothing.
627
703
  - **Next.** Every ask she sends announces the key she will sign with next.
628
704
  The door holds two pks for her: the one that may speak now, and the one
629
705
  it vouched for. Whichever speaks first wins, and the other dies. There is
@@ -709,12 +785,12 @@ what makes three answers three. A wait that does not end is not an object,
709
785
  not silence and not unreached, and before the allowance a cycle of legal asks
710
786
  could produce one: A asks B, B answering asks A back, A answering asks B on
711
787
  the relation the first ask still holds. Now the innermost wait gives up, the
712
- silence unwinds outward, and the ask ends.
788
+ word `late` unwinds outward, and the ask ends.
713
789
 
714
- **A wait that ran out is silence, never unreached.** Unreached promises
715
- nothing was delivered and is safe to ask again. A bound that expired knows no
716
- such thing: the far door may have heard and be working still. What comes
717
- back late is not read.
790
+ **A wait that ran out is the word `late`, never silence and never
791
+ unreached.** Unreached promises nothing was delivered and is safe to ask
792
+ again. A bound that expired knows no such thing: the far door may have heard
793
+ and be working still. What comes back late is not read.
718
794
 
719
795
  The harbor keeps a patience of its own, and the two never read each other.
720
796
  What a harbor hands back as nothing came back is unreached, and unreached
@@ -722,7 +798,7 @@ says nothing was delivered: a harbor may answer it only where it knows the
722
798
  bytes never arrived, no reach for that pk, a socket that would not open, a
723
799
  link that is down. A harbor that sent them and then gave up knows no such
724
800
  thing, and must not answer at all; the ward's bound will ring, and that is
725
- silence, which promises nothing. A harbor that throws has answered nothing
801
+ `late`, which promises nothing. A harbor that throws has answered nothing
726
802
  in a louder voice, and the ward reads it as nothing: unreached. So a harbor
727
803
  may hold a shorter patience than the ward for its own reasons, a socket it
728
804
  wants back or a queue it will not grow, and whichever ends first ends the
@@ -747,7 +823,10 @@ Every arrival is judged by the door, and named by it or falls silent.
747
823
  payload names, and dispatch as `{}`. Nothing is written.
748
824
  3. For a heir: admit the signer if it is the key held for that heir or the
749
825
  key that key announced, or the key held when she removed the id. Verify
750
- the signature. Only then say anything or write anything: a removed
826
+ the signature. Read admission again, since the door judges arrivals
827
+ concurrently and a knock that raced this one may have spent the heir
828
+ while the signature was checked. Only then say anything or write
829
+ anything: a removed
751
830
  relation is `removed`, a being not back this run is `absent`, a knock
752
831
  with no key is `unannounced`, a number already honoured is `repeated`,
753
832
  and none of those writes. Else spend the number and settle the keys, so
@@ -783,7 +862,11 @@ share no key learn nothing from each other.
783
862
 
784
863
  Four algorithms, named once and never negotiated: Ed25519 signs, X25519
785
864
  agrees, SHA-256 hashes, AES-256-GCM encrypts with key and nonce derived
786
- together by HKDF-SHA-256 under an empty salt and the label `quo-seal`. The
865
+ together by HKDF-SHA-256 under an empty salt and the label `quo-seal`. That
866
+ label is the message cipher's and no other: HKDF appears twice in this kit,
867
+ here from an agreement and again at the ward key from a seed, and the three
868
+ labels, `quo-seal`, `quo-ward-sign`, `quo-ward-seal`, are three so that two
869
+ derivations never answer to one name. The
787
870
  ephemeral pk is the additional authenticated data of every box. A small-order
788
871
  public key verifies nothing; an all-zero agreement is refused. All four are
789
872
  in WebCrypto, which is why the ward names no package -- on any terrain that
@@ -800,14 +883,17 @@ on the bytes.
800
883
  ```
801
884
  ask on the wire box = ephemeral X25519 pk (32) || AES-GCM( payload || signature (64) )
802
885
  sealed to the ward padlock. nothing rides outside it.
803
- payload = JSON { to, by, next, seq, time, hops?, method?, args }
804
- signed by `by`. to, by, next: 64 hex. to, next may be null.
805
- to names the heir, or null for the public being.
886
+ payload = JSON { to, by, next, seq, time, hops?, method?, args? }
887
+ signed by `by`. to, by, next: 64 lowercase hex. to, next may be null.
888
+ to names the heir, or null for the public being. seq is a whole
889
+ number from one. args, when present, is one object of values.
806
890
  hops is reserved: a whole number, never below zero,
807
891
  refused at zero, and nothing sets it.
808
892
  reply on the wire box = ephemeral X25519 pk (32) || AES-GCM( reply || signature (64) )
809
893
  sealed to the ask's ephemeral pk, signed by the ward key
810
894
  reply = JSON { object, seen } | { silence: true } | { quo: word }
895
+ seen is always present: the digest, 64 hex, on a named ask that
896
+ had one, and null otherwise, the empty ask included.
811
897
  word: removed | absent | unannounced | repeated | threw. only to a key the door bound.
812
898
  ```
813
899
 
@@ -854,8 +940,9 @@ It owns nothing durable. It is three things, all in the harbor's hands:
854
940
  its seed, its partition, and the classes its beings are made of. The
855
941
  partition names each class and the harbor holds the bodies, so a ward is
856
942
  whole only where all three are, and a harbor that keeps one remembers where
857
- the other two came from. It writes as it runs and never decides, asks, or
858
- learns whether anything was kept. Between one run and the next, a ward is
943
+ the other two came from. It writes as it runs, says so after every write,
944
+ and never decides, asks, or learns whether anything was kept. Between one
945
+ run and the next, a ward is
859
946
  nothing at all.
860
947
 
861
948
  One ward is one runtime and one language, and every being in it shares both.
@@ -871,8 +958,9 @@ list is a promise, not an accident: `test/terrain.test.ts` fails the build
871
958
  both when a file names a platform and when it reaches for a global outside
872
959
  the list, and when the list names one the tree has stopped using.
873
960
 
874
- The package exports raw TypeScript, extension and all, on every specifier, so
875
- Node loads it directly and every other terrain reaches a ward through a
961
+ The package exports the emitted `dist/`, JavaScript with a declaration
962
+ beside it, on every specifier, so plain Node imports it; the tree runs the
963
+ source directly, and every other terrain reaches a ward through a
876
964
  bundler. `test/bundle.test.ts` bundles the three words and runs them, and
877
965
  asserts the artefact carries nothing a terrain cannot provide.
878
966
 
@@ -887,8 +975,9 @@ of every terrain at once. Five run it: Node, a browser, workerd, Deno and
887
975
  Bun. Bun is the one that is not V8, so "the language alone" is checked
888
976
  against two implementations of the language and not one.
889
977
 
890
- `npm run check` is Node alone, and stays fast. `npm run check:terrain` is the
891
- browser and the edge, kept apart because a browser is a download and not a
978
+ `npm run check` is Node alone, and stays fast. `npm run check:terrain` is
979
+ every other terrain, the browser, workerd, Deno and Bun, kept apart because
980
+ each is a binary of its own and the browser is a download and not a
892
981
  package: a fresh clone needs `npx playwright install chromium` first, and is
893
982
  told so in one sentence rather than a stack trace.
894
983
 
@@ -897,7 +986,9 @@ told so in one sentence rather than a stack trace.
897
986
  Everything durable a ward has is here, every secret included, and nothing
898
987
  here is ever in a being's cells. Values only, so the harbor may persist it as
899
988
  it likes: as this process's objects, as a row, as a line of JSON on a disk. A
900
- reboot from its JSON is the same ward. The shape is `src/ward/partition.ts`.
989
+ reboot from its JSON is the same ward. A harbor that keeps it copies it
990
+ through JSON and never structured-clones it: what the ward hands out is
991
+ behind the cells guard. The shape is `src/ward/partition.ts`.
901
992
 
902
993
  ```
903
994
  partition
@@ -908,8 +999,10 @@ partition
908
999
  occupants id -> heir pk
909
1000
  knocks <ward>:<heir> | public:<ward> -> { current, next, spoke, sent, seq } before take
910
1001
  spoke: bytes came back once. sent: bytes went out once, answered or not
1002
+ bounded, oldest out, and one that answered outlives one that never did
911
1003
  answered <ward>:<heir> | public:<ward> -> true knocked and answered
912
- minted the last eight pks her side minted
1004
+ minted the last eight pks her side minted. nothing in the ward reads it: it is there to
1005
+ be looked at, and a kit that keeps the list empty holds the same ward
913
1006
  heirs heir pk -> { being, id, current, announced, fresh, mark, spent } the door's view of every occupant
914
1007
  gone heir pk -> { current, announced } the keys held when an id was removed, bounded, so their
915
1008
  holder hears `removed` and nobody else hears a thing
@@ -921,6 +1014,12 @@ alone: an invitation carries the heir to whoever it is for, and anyone
921
1014
  holding one could quote that heir back inside an invitation naming a ward of
922
1015
  their own.
923
1016
 
1017
+ Only take ends a knock record, so the list is bounded like `gone`: past the
1018
+ count the oldest go, and one that was answered outlives one that never was,
1019
+ since an answered knock is a relation she may still take. A being who knocks
1020
+ without ever taking keeps a fixed number of keys behind her, not one per
1021
+ invitation she ever met.
1022
+
924
1023
  The version is one value and it does not move until 1.0.0. There is nobody
925
1024
  holding a partition of another shape to tell apart: if the shape changes, a
926
1025
  partition is thrown away, not migrated and not counted. A ward opening a
@@ -928,6 +1027,17 @@ version it cannot read throws at birth and does not boot. Birth is where a
928
1027
  ward is allowed to be loud; silence is the door's word, for asks that were
929
1028
  made, and no ask has been made yet.
930
1029
 
1030
+ The version says which shape, and the ward reads the shape as well, once, at
1031
+ birth: every field above that the ward, the door or the heirs later act on
1032
+ without looking again. A partition this ward wrote is that shape by
1033
+ construction. One adopted from elsewhere was written by a hand, another kit,
1034
+ or a file that was cut short, and a `spent` that is not a list or a `mark`
1035
+ that is not a number is a door that honours every number, or one that
1036
+ rejects where it promised a word. A ward that meets one throws at birth with
1037
+ the path that failed, which names what is wrong to whoever is holding the
1038
+ file. A being's own cells are read no further than the two records the ward
1039
+ keeps in them: what she puts in her own is hers, of any shape JSON carries.
1040
+
931
1041
  What a ward can read is a list, `READS`, and today it has one member. The
932
1042
  list and the step that carries an older partition forward exist before
933
1043
  1.0.0 because after it there is nowhere to put them. A partition holds every
@@ -949,7 +1059,9 @@ A constructor that throws on a restart takes only herself down: she is
949
1059
  absent this run, no door, so `absent` at her door to the keys she bound and
950
1060
  silence to strangers, and her cells sit untouched waiting for the run that
951
1061
  can read them. The ward is up and so is everyone
952
- else. A class the harbor no longer knows is the same absence, and so is a
1062
+ else. Her row is hers while she is absent: the owner sees her as absent, no
1063
+ class boots under her key, and the owner may unboot her. A class the harbor
1064
+ does not hold this run is the same absence, and so is a
953
1065
  class the harbor holds at a body the cells were not written for: which body
954
1066
  a ward reboots on is the harbor's decision, and a ward cannot tell an old
955
1067
  one from a new one. Loss of the partition is loss of every relation,
@@ -989,10 +1101,10 @@ renders anyone's and holds no list of its own.
989
1101
 
990
1102
  ```
991
1103
  ask() -> { asks: [boot, public, invite, knock, remove, unboot],
992
- notes: { pk, beings: { key: { class, public, digest } } } }
1104
+ notes: { pk, beings: { key: { class, public, digest, absent? } } } }
993
1105
  ask('boot', { key, class }) -> { booted: key } | { error }
994
1106
  ask('public', { key }) -> { public: key } | { error }
995
- ask('invite', { being, id }) -> invitation | null | { error }
1107
+ ask('invite', { being, id, notes? }) -> invitation | null | { error }
996
1108
  ask('knock', { being | { boot: class, key },
997
1109
  id, invitation, method?, args?, wanted? })
998
1110
  -> { taken: id | null, answer } | { error: 'silence' | 'unreached' | ... }
@@ -1004,16 +1116,24 @@ anything else -> { error: 'unknown ask' }
1004
1116
  - The owner is a caller like any other: `wanted` says what its knock may
1005
1117
  spend, and saying nothing is the ward's default, exactly as for a being.
1006
1118
  - The describe runs every being's own describe as `OWNER` and hashes it; a
1007
- being that throws or falls silent there shows a null digest.
1008
- - Boot refuses a key already booted and a class the harbor does not know; a
1009
- boot that made nobody leaves the partition as it found it. A throw at
1010
- birth is that boot's error, and nothing half-lives.
1119
+ being that throws or falls silent there shows a null digest. A being
1120
+ absent this run is listed with a null digest and `absent: true`.
1121
+ - Boot refuses a key that has a row in the partition, booted this run or
1122
+ absent, and a class the harbor does not know; a boot that made nobody
1123
+ leaves the partition as it found it. A throw at birth is that boot's
1124
+ error, `{ error: 'threw at birth' }`, and nothing half-lives; a being's
1125
+ own boot answers null for it.
1011
1126
  - Public marks a being already booted as the ward's one public being. It
1012
1127
  refuses a key not booted, the ward's own pk, and a second public being
1013
1128
  while one stands, since marking a second would leave the first holding
1014
1129
  every relation she had, reachable by nobody at the bare pk and told by
1015
1130
  nobody she was replaced. Marking the one already public again is
1016
- answered, and changes nothing.
1131
+ answered, and changes nothing. A public being absent this run is
1132
+ reachable by nobody already, so the mark may move to another. A null key
1133
+ takes the mark off: the being stays booted with every relation she holds,
1134
+ and the ward answers arrivals for no heir with silence as one that never
1135
+ had a public being does. Retiring her is not destroying her, and the mark
1136
+ is free for another.
1017
1137
  - Invite on the ward's own pk mints an owner, and only the root may ask it:
1018
1138
  from the door it is answered as an invite on nobody. The ward has
1019
1139
  occupants, its owners, and no standings: a knock for the ward itself is a
@@ -1034,7 +1154,9 @@ anything else -> { error: 'unknown ask' }
1034
1154
  heir with silence as one that never had a public being does. The ward
1035
1155
  itself is refused, for the reason knock is: it would be a ward deleting
1036
1156
  itself from inside its own map, leaving its owners bound to a door that is
1037
- gone.
1157
+ gone. An absent being is unbooted the same way: she has no stance to speak
1158
+ for her, so the ward closes her heirs itself, and her occupants hear
1159
+ `removed`.
1038
1160
  - The owner's remove is the mirror of its knock: a relation out of a being,
1039
1161
  by id, and the id may be an occupant or a standing, since the two share
1040
1162
  one namespace. The being's own remove says nothing; the owner hears
@@ -1099,12 +1221,24 @@ Not stressed with:
1099
1221
 
1100
1222
  A harbor is what a device already has, offered to Quo: processes, storage, a
1101
1223
  network, entropy, a clock. It fits into a device carved up by its owner,
1102
- users, containers, mounts, profiles, and asks for none of them. It knows no
1103
- being, holds no id, reads no partition, and is nobody outside its device.
1224
+ users, containers, mounts, profiles, and asks for none of them. It judges
1225
+ nothing, holds no id, chooses no class, and is nobody outside its device.
1226
+
1227
+ It makes every being of every ward it serves, because `instantiate` is in
1228
+ the ground and the ward calls it, and it keeps what it made. That is not
1229
+ knowing a being. It has her object and knows nothing about her: not what she
1230
+ answers, not who her occupants are, not which of her cells is a secret. It
1231
+ never reads a partition to decide anything, and it never hands one out
1232
+ except as the values a store keeps.
1104
1233
 
1105
1234
  The harbor:
1106
1235
 
1107
- - Boots wards as processes, one seed each, and keeps each ward's partition.
1236
+ - Boots wards as processes, one seed each, and keeps each ward's partition:
1237
+ saves it when the ward says it wrote, one save at a time per ward and in
1238
+ the order it was told, so a being driven in process is kept the way one
1239
+ reached through a door is. A save that fails is the harbor's to count and
1240
+ never a door's to answer: the door answered bytes, and a full disk is not
1241
+ a reason the far side may hear.
1108
1242
  - Holds the class bodies for its wards, and remembers for each ward where
1109
1243
  its bodies came from, so that a restart is on the same bodies unless the
1110
1244
  harbor decides otherwise. Constructs a being when a ward names a class
@@ -1115,6 +1249,16 @@ The harbor:
1115
1249
  - Passes every ward the ground, once, at birth. Receives a door and an ask.
1116
1250
  Hands the ask to exactly one holder, by the device's own rules. That
1117
1251
  holder is the ward's owner.
1252
+ - Hands its own device's code the beings it made for a ward, by key, and the
1253
+ keys it has. This is not a path around a door. The object is already in
1254
+ that process, made there a moment ago by the harbor itself, and reaching
1255
+ it is the device's own code calling its own object, the same reach a being
1256
+ has on one she booted herself. Nothing of it crosses an edge, so there is
1257
+ no door it could have passed instead. A key with no object is a being who
1258
+ is not here this run. What the device does not get is the partition: it
1259
+ holds every seed the ward has, and a side that wants to know which beings
1260
+ there are, or which one is public, asks the ward through the ask pointer,
1261
+ which is the only thing that answers for a ward anyway.
1118
1262
  - Keeps the map of ward pk to door for its own wards, and ward pk to reach
1119
1263
  for foreign ones. Learns its own wards' pks by asking them. Learns foreign
1120
1264
  pks however it likes.
@@ -1141,8 +1285,8 @@ Not stressed with:
1141
1285
  silence, and it never answers on a ward's behalf.
1142
1286
  - Fanning out, broadcasting, or forwarding to a pk other than the one it was
1143
1287
  given. One pk is one ward is one door.
1144
- - Beings, ids, keys inside a relation, classes as things to choose,
1145
- invitations, or what any partition contains.
1288
+ - Choosing a class, deciding an id, reading the keys inside a relation,
1289
+ minting an invitation, or acting on anything a partition contains.
1146
1290
  - Judging anything. A ward judges its door. The harbor delivers to it.
1147
1291
  - Speaking Quo. It is nobody's occupant and holds no standing anywhere. The
1148
1292
  harbor is not a ward and is nobody's.
@@ -1154,12 +1298,15 @@ one hop: a pk that is not its own and not a direct peer's is nothing. It
1154
1298
  keeps no lease: two of them may hold one seed and one partition, which is
1155
1299
  the broken vouch every real harbor refuses, kept here so that the tests can
1156
1300
  show what divergence looks like. Every ward and being assertion in the tree
1157
- is made on it, so that the network never hides a fault in the words.
1301
+ is made on it first, so that the network never hides a fault in the words;
1302
+ the harbor core then passes the same suite over memory stores.
1158
1303
 
1159
1304
  What a harbor on a device keeps is a ward's three parts under one name: the
1160
1305
  seed, the partition, and a **ward record**, which says where the class
1161
- bodies come from and which being is the user's. That is the **store**,
1162
- `src/harbor/store.ts`: list, load, put, save the partition after a call,
1306
+ bodies come from and which being is the user's. `user` is a key and nothing
1307
+ else: a label the device's own code hands back to get the being it made,
1308
+ never read to route a byte or judge an ask. That is the **store**,
1309
+ `src/harbor/store.ts`: list, load, put, save the partition when the ward wrote,
1163
1310
  save the record after a boot learned the pk, take a ward out as the first
1164
1311
  move of a migration, and keep the directory's hints, a pk to a URL, across
1165
1312
  a restart. A name already kept is refused. A store reads nothing it keeps
@@ -1183,14 +1330,17 @@ WebSocket, and this tree holds either end of a line and never a listener:
1183
1330
  who accepts a socket is the terrain's business. A reach reads nothing; a
1184
1331
  harbor opens no box but its own probe's.
1185
1332
  Nothing comes back only where the reach knows nothing was delivered: no such
1186
- pk at the far end, a connection that would not open, a line already gone. A
1333
+ pk at the far end, a connection that would not open or closed before it
1334
+ opened, a line already gone, a status from a request that says the listener
1335
+ did not take the bytes, refused on their face or with nobody behind the
1336
+ gateway. A
1187
1337
  reach that sent the bytes and lost the line after answers nothing at all,
1188
1338
  and the ward's bound ends the ask. Every reach passes
1189
1339
  `src/conformance/reach.ts` untouched, and the frames are pinned in
1190
1340
  `vectors/wire.json`.
1191
1341
 
1192
1342
  A reach also carries the **wire suite**: which frames these are, and which
1193
- four algorithms seal what they travel with. It is one number, it is not
1343
+ five algorithms seal what they travel with. It is one number, it is not
1194
1344
  negotiated, and today it is 1. It rides where a line is opened and never on
1195
1345
  an ask: in the text frame a socket announces itself with, and as the header
1196
1346
  `quo-suite` on a request. So an ask is still bytes from the first one, with
@@ -1209,7 +1359,7 @@ refused as it is written: the number is compared as it was sent, so a suite
1209
1359
  is one spelling and not a family of them.
1210
1360
 
1211
1361
  This is the only place a second suite could ever be told from the first.
1212
- The four algorithms are named once and never negotiated, which is right: a
1362
+ The five algorithms are named once and never negotiated, which is right: a
1213
1363
  choice offered on the wire is a choice a stranger can push. But named once
1214
1364
  is not the same as unnameable, and a kit that must one day seal differently
1215
1365
  has to be able to say so to a kit that cannot, or the day it arrives every
@@ -1221,9 +1371,14 @@ is: the store and the reach put together under the ground. It boots every
1221
1371
  ward the store keeps, keeps the map of ward pk to door for its own wards
1222
1372
  and the **directory**, pk to reach, for foreign ones, carries bytes to a
1223
1373
  pk and delivers bytes from the wire to one door. The directory is filled
1224
- three ways, in this order: its own doors; a socket a dialer holds to it,
1374
+ four ways, in this order: its own doors; a socket a dialer holds to it,
1225
1375
  bound once the door behind the dialer's claim has proved it, and unbound
1226
- when the line closes; and a hint, a pk at a URL, kept in the store.
1376
+ when the line closes; the claims of a listener this harbor dialed, proven
1377
+ the same way and reached through that line; and a hint, a pk at a URL,
1378
+ kept in the store. A hint never displaces a reach proven at a door. An
1379
+ announce names at most sixty-four pks, proven a few at a time, and is the
1380
+ newest word: a proof still in flight from an earlier announce on the same
1381
+ line binds nothing when it lands.
1227
1382
 
1228
1383
  An announce is a claim, and a claim binds nothing until proven: anyone who
1229
1384
  can reach a listener could otherwise name a pk that is not theirs and take
@@ -1238,8 +1393,9 @@ listener proves the dialer's claims and the dialer the listener's. What a
1238
1393
  relay that genuinely reaches a ward elsewhere can still do is forward the
1239
1394
  probe and pass, and then it is a rendezvous for that ward like any other,
1240
1395
  able to drop and nothing more. This is the one box a harbor ever opens,
1241
- the one it sealed itself, and it reads nothing from it but whose key
1242
- signed. One rule makes a **rendezvous** of
1396
+ the one it sealed itself, and it reads nothing from it but that it is the
1397
+ silence a door owes such a box, signed by the claimed key. One rule makes a
1398
+ **rendezvous** of
1243
1399
  any listener: bytes that arrive from the wire go to an own door or to a
1244
1400
  socket this harbor holds for that pk, and never onward by request. So a
1245
1401
  harbor that cannot be dialed is reached through the one it dialed, by
@@ -1253,18 +1409,28 @@ with a wait that doubles from a second to thirty when the line drops, and
1253
1409
  while it is dialed it is one of the harbor's fallbacks, where a pk nobody
1254
1410
  here knows is sent. A device that slept, a phone in a pocket, comes back
1255
1411
  with that wait frozen and, often, its socket closed under it by the system
1256
- without a word, so the dialer takes one call from the device, `wake`: a
1257
- line in hand is made to announce, and a dead one closes under the word and
1258
- is dialed again; a line that is down is dialed now, the wait called off; a
1259
- dial in flight is left alone. Fallbacks are a list and a pk is tried down it in
1412
+ without a word, so the dialer takes one call from the device, `wake`:
1413
+ whatever line it holds, open or still opening, is put down and a new one is
1414
+ dialed now, the frozen wait called off. Nothing can tell a line the system
1415
+ dropped from a live one, and asking would cost a round trip the four words
1416
+ do not have; an announce written into a dead line is taken into the send
1417
+ buffer and errors only when TCP gives up, minutes later, and for all of it
1418
+ every ask to a pk bound behind that line hears `late`. Dialing costs one
1419
+ handshake when the line was fine, and an ask made meanwhile waits on the new
1420
+ socket. A line put down this way closes when the system gets round to it,
1421
+ gives back what it took, and dials nothing: only the line the dialer still
1422
+ holds dials again. Fallbacks are a list and a pk is tried down it in
1260
1423
  order: a harbor may dial more than one listener, and a rendezvous is a
1261
1424
  listener and nothing more, so a ward is never reachable through one place
1262
1425
  by anything but its own choice. A line that drops takes only its own place
1263
1426
  out of the list. A ward is born on the core by minting a seed under a name,
1264
1427
  leaves it by being dropped, the partition written first, and arrives by
1265
- being adopted, same seed, same pk. What a terrain adds is a store of its
1266
- own, a loader for the class bodies, and the lease its device offers; what
1267
- it never touches is a ward.
1428
+ being adopted, same seed, same pk. Adopting is the one path a partition
1429
+ written elsewhere takes, so it is where the ward's shape check is met: one
1430
+ that will not boot is not adopted, it goes back out of the store, and the
1431
+ only copy is the one the caller is still holding. What a terrain adds is a
1432
+ store of its own, a loader for the class bodies, and the lease its device
1433
+ offers; what it never touches is a ward.
1268
1434
 
1269
1435
  ## The being
1270
1436
 
@@ -1285,8 +1451,7 @@ describes herself, per asker, by answering the empty ask.
1285
1451
 
1286
1452
  Not stressed with: where anyone lives; crypto, keys, wire, storage, clocks,
1287
1453
  or the harbor; strangers, because nobody her ward cannot name reaches her;
1288
- whether an occupant is a person, a model or a program; making beings, because
1289
- only the ward instantiates.
1454
+ whether an occupant is a person, a model or a program.
1290
1455
 
1291
1456
  ### Her obligations
1292
1457
 
@@ -1313,9 +1478,11 @@ only the ward instantiates.
1313
1478
  asks is always a new call. The one exception is the public being, who is
1314
1479
  reached with no heir and no count: the same bytes reach her twice, and
1315
1480
  her answer must be safe to repeat.
1316
- 8. Beings do not make beings. A being that could create would hold class,
1317
- memory and key, and there would be no ward. A being that wants a child
1318
- gets one from outside, as an invitation handed to her.
1481
+ 8. A being may make a being of her own ward, by class name and under a key
1482
+ she chooses, and holds no relation to her until one is invited and taken
1483
+ like any other; the ward builds the stance and the harbor holds the
1484
+ class, so she never touches either. Only the owner reaches into a being
1485
+ from outside.
1319
1486
  9. Whatever her ward cannot name is not hers to worry about: what the ward
1320
1487
  does with an arrival it cannot name is the ward's.
1321
1488
 
@@ -1332,16 +1499,30 @@ The raw shape needs no import from the kit. The kit also offers a base class,
1332
1499
  `for(occupant, asker)` decides whether this asker sees the ask, and so
1333
1500
  whether this asker may call it: what she shows is what she can be asked,
1334
1501
  one gate for describe and for dispatch.
1502
+ - Both statics are read off the class the object was made from, and a
1503
+ subclass that declares either **replaces** its parent's rather than adding
1504
+ to it. That is the rule and not an oversight: a being's blueprint is
1505
+ exactly what the class in front of you declares, in the order she chose,
1506
+ and a merge would hand her asks she may mean to drop and an order she did
1507
+ not write. A subclass that means to extend says so, in one spelling,
1508
+ `static override asks = { ...Parent.asks, mine: {} }`, and the same for
1509
+ cells. A parent that means to be subclassed at all annotates rather than
1510
+ infers, `static override cells: JsonObject = { ... }`, since this language
1511
+ holds a subclass's static side to its parent's and would otherwise refuse a
1512
+ subclass declaring fewer keys than the parent happened to write.
1335
1513
  - `answer` is written for her. The empty ask is `describe(asker)`, which she
1336
1514
  may override by hand. A named ask calls the method of that name with
1337
1515
  `(args, asker)`. Anything not declared, hidden from this asker, or
1338
1516
  inherited from Object's prototype is `{ error: 'unknown ask' }` and the
1339
1517
  method is never entered.
1340
1518
  - A declared ask with no method, or one named after the base's own members,
1341
- fails at birth, loudly, so a boot fails and nothing half-lives.
1519
+ fails at birth, loudly, so a boot fails and nothing half-lives. The
1520
+ method is one on her prototype chain below Object's: a class field
1521
+ holding a function is not there yet when the base checks, and the
1522
+ refusal says so.
1342
1523
  - `occupant(asker)` is the occupant record for whoever is at the door, and
1343
- undefined at a public being. `invite`, `knock`, `take`, `standings` and
1344
- `occupants` reach the stance and nothing else.
1524
+ undefined at a public being. `invite`, `knock`, `take`, `boot`, `cells`,
1525
+ `standings` and `occupants` reach the stance and nothing else.
1345
1526
 
1346
1527
  ### Examples
1347
1528
 
@@ -1375,6 +1556,7 @@ class Shop {
1375
1556
  }
1376
1557
  async answer(asker, method, args) {
1377
1558
  if (method === undefined) return { asks: [{ name: 'hello', input: {} }], notes: {} };
1559
+ if (asker.id === undefined) return { welcome: false }; // a stranger at the public door has no record
1378
1560
  const rec = this.s.cells.occupants[asker.id];
1379
1561
  if (method === 'hello' && args.invitation) {
1380
1562
  const back = await this.s.standings.knock(args.invitation, 'hi');
@@ -1408,15 +1590,18 @@ class Guest {
1408
1590
  ```
1409
1591
 
1410
1592
  A relay. Forwards every ask to one standing and never looks inside, and asks
1411
- for a short wait because she is one door of several.
1593
+ for a short wait because she is one door of several. Silence passes through
1594
+ her; a word does not, since a word out of a being is `threw` at the door,
1595
+ D13, so she says it as an error of her own.
1412
1596
 
1413
1597
  ```js
1414
1598
  class Relay {
1415
1599
  constructor(stance) {
1416
1600
  this.s = stance;
1417
1601
  }
1418
- answer(asker, method, args) {
1419
- return this.s.standings.next.ask(method, args, { time: 2000 }); // silence and unreached pass through
1602
+ async answer(asker, method, args) {
1603
+ const out = await this.s.standings.next.ask(method, args, { time: 2000 });
1604
+ return isWord(out) ? { error: wordOf(out) } : out; // unreached and late reach her asker as an error, not as a throw
1420
1605
  }
1421
1606
  }
1422
1607
  ```
@@ -1452,8 +1637,7 @@ words, and nothing is kept for a holder of an earlier one.
1452
1637
 
1453
1638
  The tree runs as TypeScript and the package ships as JavaScript. Node
1454
1639
  strips types nowhere under `node_modules`, so a consumer cannot load the
1455
- source, and 0.1.0, which shipped it, imported nowhere; 0.1.1 is the first
1456
- version a stranger can import. `npm run build` emits `dist/` from `src`
1640
+ source. `npm run build` emits `dist/` from `src`
1457
1641
  alone, one JavaScript file and one declaration file per source file with
1458
1642
  every relative import rewritten, and the exports map points there, types
1459
1643
  beside default. The
@@ -1463,11 +1647,12 @@ which is how a consumer does. `test/package.test.ts` is the one
1463
1647
  suite that meets the package as a stranger: it packs the tarball,
1464
1648
  installs it into an empty folder, and imports every entry point under
1465
1649
  plain Node. `npm pack --dry-run` shows what ships: `dist/`, the four
1466
- source folders, the vectors, this document, the README and the licence,
1467
- and nothing else. This document ships, decided here: it is the truth the
1468
- source and the vectors are read against, and a kit in another language is
1469
- written against it and nothing else. Publishing runs both gates first,
1470
- `npm run check` and `npm run check:terrain`, and refuses on a failure.
1650
+ source folders, the vectors, this document, the README, the licence and
1651
+ the notice, and nothing else. This document ships, decided here: it is the
1652
+ truth the source and the vectors are read against, and a kit in another
1653
+ language is written against it and nothing else. Publishing runs both
1654
+ gates first, `npm run check` and `npm run check:terrain`, and refuses on a
1655
+ failure.
1471
1656
 
1472
1657
  ```
1473
1658
  src/being/ the Being side. types, the base class, silence, the digest.
@@ -1514,8 +1699,9 @@ passes the same suite. Those tests are the checklist, not the mock.
1514
1699
  - `src/conformance/index.ts`: one suite of behaviours, written against the
1515
1700
  stance and one probe: a kit hands the suite its ward's heir table and
1516
1701
  bind table as values, and a forged knock, so the suite can see that a
1517
- refusal wrote nothing and a knock bound what it should. It reads them and
1518
- never writes them. With the beings in `src/conformance/beings.ts`: a
1702
+ refusal wrote nothing and a knock bound what it should. It reads the
1703
+ tables and never writes them; the forged knock is the one thing it sends
1704
+ through a door. With the beings in `src/conformance/beings.ts`: a
1519
1705
  printer, a shop, two customers, one raw being with no base class, and a
1520
1706
  member of an estate. Any ward must pass it, under any topology.
1521
1707
  - `src/conformance/estate.ts`: the estate, and the last chapter of that
@@ -1594,8 +1780,11 @@ passes the same suite. Those tests are the checklist, not the mock.
1594
1780
  reach suite against the socket framing over two lines in one process, so
1595
1781
  the frames are asserted with no network under them; the conformance
1596
1782
  suite against two harbor cores over memory stores reaching each other
1597
- in-process, drop and adopt as the migration; a restart from the store
1598
- with the hints; the dialer over a stubbed line, announce, a claim proven
1783
+ in-process, drop and adopt as the migration; a ward that moves harbor
1784
+ keeping its pk and every relation, the rendezvous told on the line in
1785
+ hand; a ward booted or dropped after a line opened, announced on that
1786
+ line, and a claim on a pk nobody holds binding nothing; a restart from
1787
+ the store with the hints; the dialer over a stubbed line, announce, a claim proven
1599
1788
  at a real door before it binds and a claim nobody there holds left
1600
1789
  unbound, fallback, unbind and the wait before it dials again; and the frames against
1601
1790
  `vectors/wire.json`, the ask, the reply, nothing delivered and the
@@ -1614,7 +1803,7 @@ passes the same suite. Those tests are the checklist, not the mock.
1614
1803
  `node:assert/strict`, pair by pair. The suite means the same thing on
1615
1804
  every terrain only if those two agree, so they are compared and not
1616
1805
  trusted.
1617
- - `test/floor.test.ts`: the four algorithms this terrain must carry, probed
1806
+ - `test/floor.test.ts`: the five algorithms this terrain must carry, probed
1618
1807
  one by one; that the arithmetic spends every one of them; and the two ways
1619
1808
  a terrain can be short -- no `crypto.subtle` at all, and a subtle without
1620
1809
  the curves -- each failing at the first call, in one sentence.
@@ -1745,7 +1934,7 @@ Decided here, so that the answer is not rediscovered:
1745
1934
  - **invite**: mint an id and get its invitation.
1746
1935
  - **knock**: an ask carrying an invitation. Binds the far side to the id.
1747
1936
  - **take**: keep an answered knock as a standing, under her own id.
1748
- - **ask**: method and args to a standing. Object, silence, or unreached back.
1937
+ - **ask**: method and args to a standing. Object, silence, or a word back.
1749
1938
  - **answer**: her one function. Object or silence out.
1750
1939
  - **the empty ask**: ask with no method. Her answer to it is her blueprint.
1751
1940
  - **blueprint**: her interface as she chooses to show it to one asker.
@@ -1759,11 +1948,13 @@ Decided here, so that the answer is not rediscovered:
1759
1948
  - **unreached**: the word for no far door reached. Retryable.
1760
1949
  - **notes**: hers, inside every occupant record. Quo never reads it.
1761
1950
  - **partition**: the ward's files. Everything durable, every secret.
1762
- - **ward record**: what a harbor keeps to boot one ward again: seed,
1763
- partition, and where its class bodies come from. The harbor's, never
1764
- the ward's.
1951
+ - **ward record**: what a harbor keeps beside a ward's seed and partition
1952
+ to boot her again: her pk, where the class bodies come from, and which
1953
+ being is the user's. The harbor's, never the ward's.
1954
+ - **lid**: the ephemeral X25519 pk an ask carries in front of its box. The
1955
+ reply is sealed to it and to nothing else. One per ask, never reused.
1765
1956
  - **edge**: one of the two seams of Quo, harbor to ward and ward to being.
1766
1957
  An object crosses once at birth, calls cross for the rest of the ward's
1767
1958
  life, and nothing else crosses.
1768
- - **ground**: the one object a harbor passes a ward. Five things.
1959
+ - **ground**: the one object a harbor passes a ward. Six things.
1769
1960
  - **door**: the ward's one voice outward. Sealed bytes in, sealed bytes out.