- commit
- 0795bb520ce4e9636a815dd16f1c1fc304c79622
- parent
- 3f4dacf2da56d04bb2ec918e0eeea982367b038e
- author
- Dami <dami.etoile@gmail.com>
| M | README.md | 2 | +- |
| M | docs/ | 10 | +++++- |
| M | docs/ | 60 | ++++++++++++++++++++++++++++++ |
@@ -46,7 +46,7 @@ Site hosting and mirroring are on by default; Marmot and GRASP are off until ena
4646 4747 **For scripts and agents**4848 49-- [Scripts and agents](docs/13-scripts-and-agents.md): a relay end to end with a key and curl, every management method including Git storage inventory, and the relay as a configuration file.49+- [Scripts and agents](docs/13-scripts-and-agents.md): a relay end to end with a key and curl, every management method including Git storage inventory, the relay as a configuration file, and a finite production network exercise.5050 - [HTTP reference](docs/14-http-reference.md): every path, method, auth and answer.5151 5252 **For developers**@@ -74,7 +74,7 @@ scripts/
7474 build-templates.mjs fold relay-templates/ into src/gen/templates.ts7575 check/ check-console.mjs check-celld.mjs check-config.mjs run by npm run typecheck; check-config also checks any file7676 dev/ dev-signer.mjs seed.mjs stage.mjs junk.mjs shot.mjs zaptest.mjs npm run dev:signer, dev:seed, dev:stage, dev:junk, dev:shot, dev:zaptest77- ops/ margin.mjs relay.mjs npm run margin; npm run relay check|plan|push|pull77+ ops/ margin.mjs network.mjs relay.mjs npm run margin; npm run test:network; npm run relay check|plan|push|pull7878 7979 Every script has an npm name (package.json), and the docs use those names: a tutorial never says node and a path.8080 wrangler.jsonc the Worker on Cloudflare@@ -87,6 +87,7 @@ wrangler.celld.jsonc the same Worker on celld (docs/16)
8787 npm test # unit and Durable Object tests8888 npm run typecheck8989 npm run test:conformance # against RELAY_URL, default ws://127.0.0.1:744790+npm run test:network -- plan # print the finite production topology; run and cleanup are manual9091 ```9192 9293 The conformance suite needs a claimed relay. Against a dev server:@@ -97,6 +98,13 @@ CLAIM=1 RELAY_URL=ws://dev.localhost:8787 npm run test:conformance
9798 9899 CI runs typecheck and the object tests on every push; the conformance suite against the Worker on `celld dev` is a separate workflow run on demand ([Hosting without Cloudflare](16-hosting-without-cloudflare.md)). Work lands through pull requests in small commits that each typecheck on their own; the branch checks and review carry the change to `main`.99100 101+The production network exercise in [Scripts and agents](13-scripts-and-agents.md)102+is an operator-run check of relay relationships. It creates five small,103+run-owned relays, uses finite one-shot jobs, samples only public events from104+the two named external relays and tears down its own relays. It is not a105+scheduled test, load test or capacity benchmark. Its private manifest supports106+manual cleanup after an interrupted run.107+100108 ## Add a management method101109 102110 1. Add an entry to `METHODS` in `src/manage.ts`: the action it needs (`roles.ts`), `reads: true` if it changes nothing, and `run`. The handler takes what it uses from the call: `str(i)` and `num(i)` for parameters, `s` for settings, `reply({ result })` or `reply({ error }, 400)` to answer. `supportedmethods`, the permission check and the moderation log read the same entry.@@ -18,6 +18,66 @@ A relay for a script, an agent or a service, from nothing to handover, without a
1818 1919 The cheap way to learn a community is its views: `GET /view/profiles` is every member's name and picture in one signed record, `GET /view/relays` is where those members also publish, and `GET /view/zaps` says what the place values. Each is one request and no websocket; the relay's information document lists which views it keeps.2020 21+## Exercise a relay network in production22+23+`npm run test:network` runs a finite, manually invoked production exercise. It24+creates five small relays, gives run-owned identities, records the topology,25+exercises the relationships, extracts a report and deletes the relays it26+created. It has no timer, workflow or standing job outside the run.27+28+The topology is deliberately small and represents different data-flow shapes:29+30+| Role | Relationship | Activity and size assumption |31+|---|---|---|32+| `peer-a`, `peer-b` | equal peers, each pulls from the other | short bursts, idle catch-up and repeat sync; both are small |33+| `satellite` | pulls selected public profiles from `relay.damus.io` and `nos.lol` | a small node samples two much larger external sources |34+| `personal` | exchanges selected notes with the peers, sends public tasks to `hub` and pulls results back | low-volume personal activity |35+| `hub` | receives tasks and publishes results for `personal`; pulls selected profile context from `satellite` | a small agent-facing relay |36+37+The task and result path is a public relay workflow. It does not represent38+confidential agent computation. The encrypted kind-4 fixture stays on the39+personal relay, and the exercise checks that it is not copied to the hub.40+External sampling is read-only and bounded to three sampled profile authors per source and one retained kind-041+profile per author. Each sync job has a 120-second wait budget; the run has a42+20-minute scenario budget, with cleanup allowed to finish afterward. A public43+source can be empty, unavailable or rate limited, so its result is reported as44+observed or inconclusive rather than treated as a capacity claim. The two45+external relays are treated as larger than this network; their size is not46+measured.47+48+Start with an offline plan, then run the exercise. The default output directory49+is private state under the user's local application data directory. A supplied50+directory must be new and is created with mode `700`.51+52+```53+npm run test:network -- plan54+npm run test:network -- run [new-output-directory] [domain]55+npm run test:network -- cleanup <output-directory>56+```57+58+The run writes a private `manifest.json` and `report.json` in that directory;59+the manifest contains the run keys and is mode `600`, so it must not be60+committed or shared. The manifest is written before the first claim and after61+each state change. The `finally` cleanup extracts final `stats` and storage62+inventory, then verifies each relay's owner before calling `deleterelay`. If a63+process loses a claim reply or stops before cleanup, run `cleanup` against the64+same directory after checking that the manifest is the intended run. Cleanup65+only follows the generated names and matching owners, and reports any relay it66+could not delete. Baseline fuel snapshots follow provisioning; final snapshots precede deletion.67+Their deltas cover the exercise and observation calls, excluding provisioning68+and teardown. The full final counters also contain provisioning usage. These69+are tenant meters, not a provider invoice. The report includes signed synthetic70+fixtures, job results, per-source coverage and operation-lock retry counts.71+A members-only source refuses an unauthenticated pull; membership alone does72+not supply a job with credentials.73+74+The checks cover bidirectional peer convergence, deduplication, idle catch-up,75+filtered task and result flow, private-event isolation, unauthorized writes and76+management, a refused members-only pull, and separation from external profile77+traffic. One-shot server jobs are removed after each check. The exercise is a78+bounded correctness and relationship test, not a load test or evidence of79+large-relay capacity.80+2181 ## Signing a request (NIP-98)2282 2383 Every management call and every door that needs a key takes an `Authorization: Nostr <base64 event>` header. The event is: