nervur 0.14.0 → 0.16.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.
@@ -1,111 +0,0 @@
1
- # Getting started — two castles
2
-
3
- Picture a castle: one gate, its own residents, its own law. A **ground** is
4
- the castle — one sovereign process, one handler where every letter arrives.
5
- Its residents are **beings**; its capabilities are **modules**; the ground
6
- under it is a **floor** — a filesystem, or a browser's IndexedDB — and the
7
- stance it takes toward the world is its **terrain**. This page raises two
8
- castles on two terrains and has them speak: a **mountain** (a server, always
9
- reachable, always remembering) and a **house of cards** (a browser tab,
10
- raised in seconds, holding what it can afford to lose). Same castle, same
11
- law, different ground under it.
12
-
13
- Everything below runs today — the bench drives this exact story in
14
- `bench/worlds/story/`.
15
-
16
- ## The mountain
17
-
18
- The machine's raise is one config and one daemon —
19
- [`nervurd`](https://www.npmjs.com/package/nervurd) is the host, and its
20
- README is the operator's full page. The five-minute shape:
21
-
22
- ```sh
23
- npm install -g nervurd
24
- nervur self mint --self ./hand.json --heir ./heir.json
25
- nervur init --config ./castle.json --self ./hand.json
26
- NERVUR_SECRET=... nervurd --config ./castle.json
27
- ```
28
-
29
- The config names the shelf, the door, the secret's environment variable,
30
- and the modules — the castle's capabilities, chosen by you:
31
-
32
- ```json
33
- {
34
- "cells": "/var/lib/nervur/castle.json",
35
- "listen": { "host": "127.0.0.1", "port": 7001 },
36
- "secret": "NERVUR_SECRET",
37
- "modules": {}
38
- }
39
- ```
40
-
41
- Keep the heir off the machine. Whoever takes the machine takes what the
42
- castle holds today; the heir is why they can never become it tomorrow.
43
-
44
- ## The house of cards
45
-
46
- The browser's raise is two calls from
47
- [`@nervur-org/floor-web`](https://www.npmjs.com/package/@nervur-org/floor-web),
48
- because a tab closes constantly and the two acts must not blur:
49
-
50
- ```js
51
- import { found, wake } from '@nervur-org/floor-web';
52
-
53
- // Once, ever: mint the identity, stand the castle, get custody back.
54
- let kept;
55
- const castle = found({ keep: (dump) => (kept = dump) });
56
- // castle.address — the name; castle.custody — the hand, the heir, the
57
- // secret: yours to keep (IndexedDB, or a mountain you trust), never the
58
- // ground's.
59
-
60
- // Every session after: same name, same residents, no identity act.
61
- // wake hands back the standing ground itself — woken.address is the name.
62
- const woken = wake({ held: kept, secret: castle.custody.secret });
63
- ```
64
-
65
- Where `kept` and `custody` live is your choice, under this terrain's honest
66
- limit: a browser may evict what it keeps — a card castle holds what it can
67
- afford to lose, and keeps what is precious in its relationship with a
68
- mountain.
69
-
70
- ## They speak
71
-
72
- A letter is a letter on every terrain: one signed envelope, carried
73
- however the two castles can reach each other — here, `fetch` to the
74
- mountain's door. First the mountain's keeper invites the card castle's
75
- founder (one signed act at the admin door — the CLI, or any client the
76
- keeper holds), and then the founder asks from the browser:
77
-
78
- ```js
79
- import { Client, Tools, Voice } from 'nervur';
80
-
81
- const me = Voice.revive(castle.custody.hand);
82
- const talk = Client({
83
- voice: me,
84
- deliver: async (envelope) => {
85
- const res = await fetch('http://127.0.0.1:7001', {
86
- body: JSON.stringify(envelope),
87
- headers: { 'content-type': 'application/json' },
88
- method: 'POST',
89
- });
90
- return res.status === 200 ? res.json() : undefined;
91
- },
92
- });
93
-
94
- const heard = await talk.ask(mountainAddress, '{ census { active } }');
95
- ```
96
-
97
- The client verifies every answer from the address alone — the mountain's
98
- word arrives signed, and a broken or missing signature is dropped exactly
99
- like silence. A stranger who was never invited gets silence too, and cannot
100
- tell refusal from absence. That is the whole protocol: **say who you are,
101
- name whom you seek, and the castle answers or keeps quiet.**
102
-
103
- ## Where to go next
104
-
105
- - [`nervur`'s README](README.md) — the library underneath both castles.
106
- - [`nervurd`'s README](../nervurd/README.md) — the operator's page: checks,
107
- rotation, backups, the door's full behaviour.
108
- - [`@nervur-org/floor-web`](../floor-web/README.md) — the web floor's
109
- terrain contract, founding and waking in full.
110
- - [`@nervur-org/species`](../species/README.md) — blueprints your castles
111
- grow beings from.
package/SECURITY.md DELETED
@@ -1,11 +0,0 @@
1
- # Security
2
-
3
- This package answers one question — by whose authority — and a hole in that
4
- answer is the most serious bug it can have.
5
-
6
- Report vulnerabilities privately to **<security@nervur.com>**. Do not open a
7
- public report. State what you ran, what you sent, and what answered; a
8
- proof of concept is welcome but not required.
9
-
10
- A person reads every report. Fixes ship as releases on the live 0.x line,
11
- and the report is credited if you want it to be.
package/admin.mjs DELETED
@@ -1,83 +0,0 @@
1
- const ADMIN = `({
2
- name: 'nervur.ground',
3
- needs: { modules: [{ module: 'memory', contract: 'nervur.memory' }] },
4
- memory: {
5
- 'aliases/*': { type: 'String', class: 'data' },
6
- wears: { type: 'String', class: 'data' },
7
- },
8
- interface: \`
9
- input RefInput { address: String!, nextPkHash: String, rights: String }
10
- type Resident { address: String!, alias: String, digest: String, active: Boolean! }
11
- type Census { residents: [Resident!]!, stored: Int!, active: Int! }
12
- type Query {
13
- census: Census @rights(is: [SELF, MEMBER])
14
- aliasOf(name: String!): String @rights(is: [SELF, MEMBER])
15
- attest(module: String!): Boolean @rights(is: [SELF, MEMBER])
16
- opened: Boolean @rights(is: [SELF, MEMBER, STRANGER])
17
- wears: String @rights(is: [SELF, MEMBER, STRANGER])
18
- }
19
- type Mutation {
20
- invite(address: String!, nextPkHash: String, rights: String): Boolean @rights(is: [SELF, MEMBER])
21
- drop(address: String!): Boolean @rights(is: [SELF, MEMBER])
22
- extend(program: String): Boolean @rights(is: [SELF])
23
- create(program: String!, refs: [RefInput!], data: String, config: String): String
24
- @rights(is: [SELF, MEMBER])
25
- activate(address: String!): String @rights(is: [SELF, MEMBER])
26
- destroy(address: String!): String @rights(is: [SELF, MEMBER])
27
- upgrade(address: String!, program: String!): Boolean @rights(is: [SELF, MEMBER])
28
- alias(name: String!, address: String!): Boolean @rights(is: [SELF, MEMBER])
29
- wear(address: String): Boolean @rights(is: [SELF, MEMBER])
30
- }
31
- \`,
32
- resolvers: {
33
- Query: {
34
- census: (_, __, { registry }) => {
35
- const residents = registry.residents();
36
- return {
37
- active: residents.filter((one) => one.active).length,
38
- residents,
39
- stored: residents.length,
40
- };
41
- },
42
- aliasOf: (_, { name }, { modules }) => modules.memory.read('aliases/' + name),
43
- attest: (_, { module }, { registry }) => registry.attest(module),
44
- opened: (_, __, { modules }) => modules.memory.list('refs/').length > 0,
45
- wears: (_, __, { modules }) => modules.memory.read('wears') ?? null,
46
- },
47
- Mutation: {
48
- invite: (_, { address, nextPkHash, rights }, { modules }) =>
49
- modules.memory.write('refs/' + address, {
50
- nextPkHash: nextPkHash ?? null,
51
- rights: rights ?? 'MEMBER',
52
- }) !== undefined,
53
- drop: (_, { address }, { modules }) => {
54
- if (modules.memory.read('refs/' + address) === undefined) {
55
- return false;
56
- }
57
- modules.memory.write('refs/' + address, undefined);
58
- return modules.memory.read('refs/' + address) === undefined;
59
- },
60
- extend: (_, { program }, { registry }) => registry.extend(program) !== undefined,
61
- create: (_, { program, refs, data, config }, { registry }) =>
62
- registry.create({
63
- config: config === undefined ? undefined : JSON.parse(config),
64
- data: data ? JSON.parse(data) : {},
65
- program,
66
- refs: refs ?? [],
67
- }),
68
- activate: (_, { address }, { registry }) =>
69
- registry.activate(address) === undefined ? null : address,
70
- destroy: (_, { address }, { registry }) => registry.destroy(address) ?? null,
71
- upgrade: (_, { address, program }, { registry }) =>
72
- registry.upgrade({ address, program }) !== undefined,
73
- alias: (_, { name, address }, { modules }) =>
74
- modules.memory.write('aliases/' + name, address) !== undefined,
75
- wear: (_, { address }, { modules }) => {
76
- modules.memory.write('wears', address ?? undefined);
77
- return modules.memory.read('wears') === (address ?? undefined);
78
- },
79
- },
80
- },
81
- })`;
82
-
83
- export { ADMIN };