docs: numéroter les références du bas vers le haut, et lever une confusion

Les trois références sont empilées, chacune bâtie sur celle du dessous : la
numérotation suit désormais la pile — 1 = moteur Rust, 2 = binding wasm, 3 = SDK
JS / ORM. On s'aligne sur le niveau le plus HAUT qui répond, et on descend
seulement s'il ne répond pas.

Correction d'une confusion introduite par ma formulation : ce sont des
RÉFÉRENCES, pas des endroits où l'on écrit du code. Tout ce que cette
bibliothèque produit vit dans le polyfill ; aucune des trois couches n'est à
nous, `nextgraph-rs` est une source en lecture seule qu'on ne maintient pas.
« Ce code est de niveau 1 » veut dire « il s'aligne sur le modèle du moteur »,
jamais « il est dans le moteur ». Dit ainsi, la question « comment du code de
niveau 2 rendrait du code de niveau 1 inutile » ne se pose plus : ce qui
disparaît, c'est notre propre code de compensation, quand une couche au-dessus
finit par offrir ce qu'il fabriquait.

Ajout d'un garde-fou : ces niveaux-là n'ont rien à voir avec les « trois
niveaux » de readcap-and-nuri-model §4quinquies, qui numérotent OÙ vit une clé.
Même mot, deux axes.
This commit is contained in:
Sylvain Duchesne
2026-08-03 17:28:41 +02:00
parent 1de9be9167
commit 6a3bd9c3a9
+41 -17
View File
@@ -106,28 +106,52 @@ it outranks cost, latency and convenience. When the shape and the cost conflict,
the shape and attack the cost elsewhere — and if it truly cannot be solved, say so
rather than bend the model quietly.
### The three references, in cascade
### The three references, numbered bottom-up
"NextGraph" is not one layer, and conflating them is how a fact about one gets asserted
about another. Walk them **top down, stop at the first that answers**:
about another. They are **stacked**, each built on the one below, so they are numbered
from the bottom:
| # | Layer | Where | Rule |
|---|---|---|---|
| 1 | **JS SDK / ORM** | `@ng-org/orm`, `@ng-org/shex-orm` — source in `sdk/js/orm` (TypeScript) | Covers the need fully → **do not implement it here.** Pass through. |
| 2 | **wasm binding** | `@ng-org/web` — source in `sdk/js/lib-wasm` (77 exported methods) | Level 1 absent or unsatisfactory → build on the **equivalent binding call**. |
| 3 | **Rust engine** | `engine/``repo`, `verifier`, `net`, `broker`, `wallet` | Nothing above answers → hold to the engine's **MODEL**: cardinalities, addressing units, what a structure can and cannot express. |
| # | Layer | Where |
|---|---|---|
| **3** | **JS SDK / ORM** | `@ng-org/orm`, `@ng-org/shex-orm` — source in `sdk/js/orm` (TypeScript) |
| **2** | **wasm binding** | `@ng-org/web` — source in `sdk/js/lib-wasm` (77 exported methods) |
| **1** | **Rust engine** | `engine/``repo`, `verifier`, `net`, `broker`, `wallet` |
Level 3 is the deepest and the one whose facts are hardest-won — but reaching it means
**inventing a surface**, because the JS shape does not exist yet. So always **say which
level a choice came from**. A level-1 passthrough is a fact; a level-3 shape is a bet
constrained by the engine. Presenting them alike is what manufactures false certainty —
`inbox_post_link` was cited across eight files as a planned NextGraph API when it was
only a name proposed in [`docs/fork-inbox-fallback.md`](./docs/fork-inbox-fallback.md).
**These are REFERENCES, not places we write code.** Every line this library ships lives
in the polyfill; none of these three layers is ours to touch, and `nextgraph-rs` is a
read-only source of truth. Saying "level 1" about a piece of our code means *"it is
aligned on the engine's model"* — never *"it lives in the engine"*.
Concretely for the inbox: level 1 has nothing, level 2 has **no `inbox` method at all**
(and the verifier has no `InboxPost` arm), so `inbox.*` is level 3 — held to the engine's
model (one inbox ↔ one repo, addressed by `(overlay, pubkey)`, no target document in the
message) with a JS surface of our own making.
**Which reference to align on: take the HIGHEST one that answers, and go down only when
it does not.**
- **Level 3 answers fully → do not implement it here.** Pass through. Compensation code
that doubles a working SDK function is code to delete later, and it diverges meanwhile.
- **Level 3 is absent or unsatisfactory → align on the level-2 call** that does the job.
Ergonomics are lost, semantics are kept — and migrating later means moving up one
step, not rewriting.
- **Nothing at level 2 either → align on the level-1 MODEL**: cardinalities, addressing
units, what a structure can and cannot express.
Level 1's facts are the hardest-won, but aligning there means **inventing a JS surface**,
since none exists yet. So always **say which level a choice came from**. A level-3
passthrough is a fact; a level-1 shape is a bet constrained by the engine. Presenting
them alike is what manufactures false certainty — `inbox_post_link` was cited across
eight files as a planned NextGraph API when it was only a name proposed in
[`docs/fork-inbox-fallback.md`](./docs/fork-inbox-fallback.md).
Concretely for the inbox: level 3 has nothing, level 2 has **no `inbox` method at all**
(and the verifier has no `InboxPost` arm), so `inbox.*` is aligned on level 1 — the
engine's model (one inbox ↔ one repo, addressed by `(overlay, pubkey)`, no target
document in the message) with a JS surface of our own making.
> **Do not confuse these levels with the other "three levels" in this repo.**
> [`docs/readcap-and-nuri-model.md`](./docs/readcap-and-nuri-model.md) §4quinquies numbers
> *where a cap is stored* (wallet root key → the Store/User branch registers → the local
> in-memory cache). Same word, unrelated axis: these three are **layers of NextGraph to
> align on**, those three are **places a key lives**. When it is not obvious from the
> sentence, say "reference level" or "storage level".
- SDK-identical surface: the client wraps the real `ng` (a Proxy that forwards
everything and overrides only what must be emulated) and `useShape`. The real