nervur 0.17.0 → 0.18.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/README.md CHANGED
@@ -17,13 +17,16 @@ Nothing else is Quo.
17
17
  beings and judges its door.
18
18
  - **Being.** One ordinary object, one voice.
19
19
 
20
- [`protocol/SPEC.md`](protocol/SPEC.md) is the truth. It is the protocol
21
- alone: what any ward in any language must do for its bytes to be Quo. It is
20
+ The truth is the spec, at <https://quo.systems/spec>, with the vectors it
21
+ is proved by at <https://quo.systems/vectors>. It is the protocol alone:
22
+ what any ward in any language must do for its bytes to be Quo. It is
22
23
  self-contained and assumes nothing from any other document, this README
23
- included. Read it first.
24
- [`quo-kit.md`](quo-kit.md) is this kit: what one TypeScript
25
- implementation chose and another kit may refuse. It assumes the spec, and
26
- where the two disagree the spec wins.
24
+ included. Read it first, at the source, which is Quo's and not this
25
+ package's to carry.
26
+
27
+ What this one kit chose, and another kit may refuse, is documented at
28
+ <https://nervur.org/docs>. It assumes the spec, and where the two disagree
29
+ the spec wins.
27
30
 
28
31
  ## This package
29
32
 
@@ -33,8 +36,6 @@ source it was emitted from, because Node strips types nowhere under
33
36
  `node_modules`.
34
37
 
35
38
  ```
36
- protocol/ the shelf a kit in any language reads: SPEC.md and the vectors, no code
37
- protocol/vectors/ fixed inputs and outputs, so another language proves its bytes
38
39
  src/being/ the Being side: what a being author imports, if anything
39
40
  src/ward/ the ward: the Ground contract, door, seal, arithmetic, heirs, stance, allowance
40
41
  src/harbor/ MemoryHarbor, and the harbor core with its store, reach and dialer
@@ -74,32 +75,30 @@ import { Stand } from 'nervur/vector';
74
75
 
75
76
  ## Another language
76
77
 
77
- The hand to a kit in another language is one folder, `protocol/`, and it
78
- holds two things of two kinds. `SPEC.md` is the protocol, and it assumes
79
- nothing: a kit is written against it and against nothing else here. The
80
- vectors beside it are the byte-level hand, everything a stranger can
81
- observe: `protocol/vectors/arithmetic.json`, the primitives the seal rests
82
- on, SHA-256, Ed25519, X25519, HKDF and AES-256-GCM;
83
- `protocol/vectors/framing.json`, Quo's own, the ward pk, the digest, the
84
- signed ask body, the sealed shapes, the invitation and the knock;
85
- `protocol/vectors/wire.json`, the frames on a socket and the one request a
86
- door takes; and `protocol/vectors/door.json`, the door's thirteen cases,
87
- each one an arrival a ward will not answer, with the bytes that arrive, the
88
- bytes that leave and the partition's digest on both sides of the judgement.
89
- They import by name,
90
- `nervur/protocol/vectors/framing.json`, so a kit's own suite can
91
- read them from the package. A kit reproduces them or it is not this
92
- protocol. `door.json` is also replayed from outside, by a verifier holding
93
- no key, against a kit standing in vector mode, which `SPEC.md` describes
94
- under that name. This kit stands in it with `Stand` from `nervur/vector`,
95
- which is vector mode and names no runtime: put it behind any listener that
96
- hands it a request body and returns what it answers.
97
-
98
- Nothing outside that folder is the protocol. `src/` is this kit's
78
+ The hand to a kit in another language is Quo's own and not this package's.
79
+ The spec is the protocol and assumes nothing: a kit is written against it
80
+ and against nothing else. The vectors beside it are the byte-level hand,
81
+ everything a stranger can observe: `arithmetic.json`, the primitives the
82
+ seal rests on, SHA-256, Ed25519, X25519, HKDF and AES-256-GCM;
83
+ `framing.json`, Quo's own, the ward pk, the digest, the signed ask body,
84
+ the sealed shapes, the invitation and the knock; `wire.json`, the frames on
85
+ a socket and the one request a door takes; and `door.json`, the door's
86
+ thirteen cases, each one an arrival a ward will not answer, with the bytes
87
+ that arrive, the bytes that leave and the partition's digest on both sides
88
+ of the judgement. All of it is at <https://quo.systems>, downloadable and
89
+ versionless, and a kit reproduces the bytes or it is not this protocol.
90
+
91
+ `door.json` is also replayed from outside, by a verifier holding no key,
92
+ against a kit standing in vector mode, which the spec describes under that
93
+ name. This kit stands in it with `Stand` from `nervur/vector`, which is
94
+ vector mode and names no runtime: put it behind any listener that hands it
95
+ a request body and returns what it answers.
96
+
97
+ Nothing in this package is the protocol. `src/` is this kit's
99
98
  interpretation, and `src/conformance/` is a checklist a kit ports rather
100
99
  than a harness it runs: it imports the base class, the silence spelling and
101
100
  this kit's store and reach, so the beings it is shown with run only in a
102
- TypeScript ward. `quo-kit.md` "The three shelves" says which is which.
101
+ TypeScript ward.
103
102
 
104
103
  ## Versions
105
104
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nervur",
3
- "version": "0.17.0",
3
+ "version": "0.18.0",
4
4
  "description": "Nervur's kit of Quo: an object asks another object and gets an answer, without knowing where it is. Being, Ward, Harbor, with the spec inside.",
5
5
  "keywords": [
6
6
  "quo",
@@ -39,11 +39,10 @@
39
39
  "types": "./dist/vector/index.d.ts",
40
40
  "default": "./dist/vector/index.js"
41
41
  },
42
- "./protocol/*": "./protocol/*",
43
42
  "./package.json": "./package.json"
44
43
  },
45
44
  "scripts": {
46
- "build": "rm -rf dist protocol && tsc -p tsconfig.build.json && mkdir -p protocol && cp ../../quo/SPEC.md protocol/SPEC.md && cp -R ../../quo/vectors protocol/vectors && cp ../../papers/quo-kit.md quo-kit.md && cp ../../papers/GETTING_STARTED.md GETTING_STARTED.md",
45
+ "build": "rm -rf dist && tsc -p tsconfig.build.json",
47
46
  "check": "node --test \"test/*.test.ts\"",
48
47
  "deep": "node --test \"test/terrain/*.test.ts\"",
49
48
  "prepublishOnly": "test \"$NERVUR_GATED\" = 1 || { echo 'publish from the root, gated once: npm run release:nervur' >&2; exit 1; }"
@@ -54,9 +53,6 @@
54
53
  "files": [
55
54
  "dist",
56
55
  "src",
57
- "protocol",
58
- "quo-kit.md",
59
- "GETTING_STARTED.md",
60
56
  "README.md",
61
57
  "LICENSE",
62
58
  "NOTICE"
@@ -1,138 +0,0 @@
1
- # Getting started
2
-
3
- Quo lets an object ask another object and get an answer, without knowing
4
- whether that other object is in the same process, on the same device, or
5
- on another planet. Three words: a harbor boots wards, a ward keeps beings
6
- and judges its door, and a being is one ordinary object with one voice.
7
- This is the shortest road from nothing to each of the three, for a
8
- stranger with a terminal. `SPEC.md` is the truth behind every sentence
9
- here and assumes nothing; `quo-dock.md` is the dock, the part a box runs.
10
-
11
- Quo is the protocol and Nervur is this kit of it. Every name you install
12
- and every command you type is Nervur's; `quo` stays on the wire, as the
13
- `quo.` route a ward's door answers at.
14
-
15
- Two packages, and you start with the one that fits what you have:
16
-
17
- - `nervur`, the library. A harbor, a ward and a being in one
18
- process, no wire, no files. For a program that wants Quo inside it.
19
- - `@nervur-org/dock`, the dock. A daemon and one command, `nervur`, that
20
- stand a box up: a person's world with a page, a model's side, an api, a
21
- door on the wire. For a box that receives people and models.
22
-
23
- The command is in the dock and not in the library, so `npm install nervur`
24
- gives you something to import and no command, and the command arrives with
25
- `npm install -g @nervur-org/dock`. That is how a kit of this shape is
26
- always named: one unscoped headline name for the library, the parts under
27
- the scope, and the CLI in the package that owns it.
28
-
29
- ## A being, in one process
30
-
31
- ```bash
32
- npm install nervur
33
- ```
34
-
35
- A being is a class with `asks`, the methods anyone may reach, each with
36
- the JSON schema of its input. Everything else on the class is hers alone.
37
-
38
- ```js
39
- import { Being } from 'nervur';
40
- import { Ward } from 'nervur/ward';
41
- import { MemoryHarbor } from 'nervur/harbor';
42
-
43
- class Shop extends Being {
44
- static asks = { price: { input: { type: 'object', properties: { item: { type: 'string' } } } } };
45
- price({ item }) {
46
- return { item, eur: 12 };
47
- }
48
- }
49
- class Customer extends Being {
50
- static asks = {};
51
- }
52
-
53
- const harbor = new MemoryHarbor();
54
- const ward = await harbor.boot('acme', Ward, { Shop, Customer });
55
- await ward.ask('boot', { key: 'shop', class: 'Shop' });
56
- await ward.ask('boot', { key: 'ana', class: 'Customer' });
57
- ```
58
-
59
- The harbor booted a ward named `acme` with two classes it may make beings
60
- of, and the ward's owner, the process itself, booted one of each by key.
61
- The ward's own asks are seven, `boot`, `public`, `invite`, `knock`,
62
- `remove`, `unboot` and `ask`, and `ward.ask()` with no method is her
63
- describe: those asks and her `notes`, the ward's `pk` and her beings.
64
-
65
- Nobody reaches a being she has not invited. An invitation is minted on a
66
- being for one id, the shop's for `ana`, and the customer knocks with it;
67
- from then she holds a standing at the shop, under the name she took, and
68
- the shop holds her as an occupant.
69
-
70
- ```js
71
- const invitation = await ward.ask('invite', { being: 'shop', id: 'ana' });
72
- const ana = harbor.objects.get(harbor.partitions.get('acme').beings.ana);
73
- await ana.knock(invitation);
74
- await ana.take('shop', invitation);
75
- console.log(await ana.standings.shop.ask('price', { item: 'bread' }));
76
- // { item: 'bread', eur: 12 }
77
- ```
78
-
79
- That is the whole protocol: a standing on one side, an occupant on the
80
- other, an ask that rides the relation and an answer that rides it back.
81
- The two beings here share a process; the same lines hold when the shop is
82
- on a box across the sea, because a standing is an address and a key, and
83
- the harbor owns the wire. `harbor.objects` is the memory harbor's hand for
84
- a test and a first program; a being on a real box is reached through her
85
- ward, never held.
86
-
87
- ## A box
88
-
89
- ```bash
90
- npm install @nervur-org/dock
91
- npx nervur init --dir ~/.nervur --ward acme --user razvan --domain acme.com --default --show
92
- npx nervur serve --dir ~/.nervur --http 8787
93
- ```
94
-
95
- `init` mints the ward `acme`, boots razvan's user being, her doorbell and
96
- the desk in it, marks it the default ward and shows it at the web route,
97
- and writes `routes.json`, the four routes of a box, `mcp.`, `web.`, `quo.`
98
- and `api.` under the domain, for a proxy to map onto the one loopback
99
- port. Without `--domain`, write it yourself; on a Mac the four are paths
100
- at one loopback address:
101
-
102
- ```json
103
- { "mcp": "http://127.0.0.1:8787/mcp", "web": "http://127.0.0.1:8787/web", "quo": "http://127.0.0.1:8787/quo", "api": "http://127.0.0.1:8787/api" }
104
- ```
105
-
106
- `serve` is the daemon, the one process over that folder, and every other
107
- command is its client. From a second terminal, a phone:
108
-
109
- ```bash
110
- npx nervur invite --dir ~/.nervur '{"being":"razvan","id":"phone"}'
111
- ```
112
-
113
- The answer carries `link`, the ward's page with the invitation in its
114
- fragment. Opened on the phone, the tab boots a harbor of its own, joins as
115
- that device, and is in: no account, nothing typed. What a model gets is
116
- the same world as tools at `mcp.`, what a program gets is the same asks as
117
- JSON at `api.`, and what another box gets is the door at `quo.`; a being
118
- answers each the same, because each is an ask at her door.
119
-
120
- The box's own doings are rows on the faculties of its dock ward, placed by
121
- the root with `nervur ask --ward dock`: a socket held to another box, an
122
- agent run for a ward, a schedule on the clock. A second box owns this one
123
- across the wire with an invitation on the ward's own pk, knocked with
124
- from there, and every owner command with `--via` from then on. Each of
125
- those, the edge, and what an estate stands beyond the init, is the
126
- "Getting started" chapter of `quo-dock.md`, proven cold on a Mac by
127
- somebody with nothing else to read.
128
-
129
- ## Your own beings on a box
130
-
131
- A box holds the dock's classes and yours. `classes/index.ts` beside the
132
- wards exports each of yours by name, and `nervur boot '{"key":"shop",
133
- "class":"Shop"}'` boots one; `nervur init --class Shop` makes the ward's home
134
- being one of yours, an organisation's ward with the org as its being. A
135
- being's asks may name who may reach them, `for`, over the record of the
136
- occupant asking, and her `cells` are what she keeps between boots: the
137
- whole of what a being is, in `SPEC.md`, and the words above the spec, a
138
- world, a home, a membership, in `WORLDS.md` and `GLOSSARY.md`.