docs: l'overlay est store-scopé ; retrait de la fausse piste "membership"
readcap-and-nuri-model — nouvelle section sur l'OVERLAY, le concept qui manquait à la référence. C'est l'espace réseau d'un STORE : deux formes (outer = BLAKE3 public du store_id, calculable par tous ; inner = BLAKE3 keyed par le ReadCapSecret, réservé aux détenteurs de la clé). Le `✌️` d'un NURI de DOCUMENT porte l'overlay de son store — VÉRIFIÉ de bout en bout, avec une contre-preuve mécanique : dans Store, get/put/del/has passent tous `&self.overlay_id`, donc tous les documents d'un store partagent le namespace de blocs et un overlay par-document est structurellement impossible. Conséquence documentée, qui contraint tout modèle de présence anonyme : le `✌️` est un pseudonyme stable et permanent de la personne, présent dans toute référence cap-less vers n'importe lequel de ses documents protected. Le même bit d'information sert à dédupliquer sans lire ET à tracer — indissociables. vision — correction d'une forme fausse. Le document affirmait « écriture = membership/permissions », en miroir de « lecture = possession de clé ». Faux : il n'y a pas de notion d'appartenance dans le modèle, uniquement des clés et des URLs. Toute forme en member/role/permission est une MAUVAISE forme. brief caps — la section « périmètre élargi : WriteCap = membership » est retirée, conservée barrée comme garde-fou, avec la leçon de méthode qui vaut plus qu'elle : lire l'état courant de nextgraph-rs pour en DÉDUIRE la forme cible est une erreur — le source contient de l'échafaudage inerte (AddMember, PermissionV0, verify_sig jamais appelé hors tests). Le source sert à vérifier un mécanisme, jamais à inférer une intention. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GbGgNEHRejVKoREvFuDFg
This commit is contained in:
@@ -82,8 +82,56 @@ regexes `net/types.rs` :
|
||||
- `did:ng:o:{repo}:c:{commit}:k:{clé}` (`RE_COMMIT` types.rs:73)
|
||||
- liste `RE_OBJECTS` `…:[cj]:{id}:k:{clé}…:l:{locator}` (types.rs:64)
|
||||
|
||||
L'`overlay` est **dérivé publiquement** de l'id du repo (`OverlayId::outer(store_id)`,
|
||||
`:259`) → id+overlay ne fuitent **aucun secret**.
|
||||
Le segment `:v:` est l'**overlay**, qui a sa propre section ci-dessous — c'est le
|
||||
point le plus lourd de conséquences pour les modèles de présence anonyme.
|
||||
|
||||
## 4bis. L'overlay est l'espace réseau d'un STORE — jamais d'un document
|
||||
|
||||
**L'overlay est l'unité d'adressage réseau d'un store.** Chez le broker, les blocs
|
||||
sont rangés sous une clé `(overlay, block_id)`, et les pairs se synchronisent
|
||||
*dans* un overlay. Deux formes par store :
|
||||
|
||||
| | Dérivation | Qui peut le calculer |
|
||||
|---|---|---|
|
||||
| **outer** | `OverlayId::outer(store_id)` = BLAKE3 **public** | tout le monde (le store_id suffit) |
|
||||
| **inner** | `OverlayId::inner(store_id, readcap_secret)` = BLAKE3 **keyed** | seulement qui détient la clé de lecture du store |
|
||||
|
||||
Cohérent avec le reste du modèle : pas de rôle ni de liste, seulement « détiens-tu
|
||||
la clé qui permet de dériver cet identifiant ». `outer` = le nom public du store,
|
||||
`inner` = son nom privé.
|
||||
|
||||
**Le `:v:` d'un NURI de DOCUMENT porte l'overlay de son STORE** (VÉRIFIÉ, chaîne
|
||||
lue de bout en bout) : `NuriV0::repo_graph_name(repo_id, overlay_id)` formate
|
||||
`o:{repo_id}:v:{overlay_id}` ; dans `doc_create` la valeur injectée est
|
||||
`store.outer_overlay()` — le store **contenant**, jamais le `repo_id`. Un `Repo` ne
|
||||
porte **aucun** champ overlay (seulement `store: Arc<Store>`) ; c'est `Store` qui
|
||||
porte `overlay_id`. **Contre-preuve mécanique** : dans `Store`, `get`/`put`/`del`/`has`
|
||||
passent tous `&self.overlay_id` au block storage — tous les documents d'un store
|
||||
partagent le namespace de blocs, donc un overlay par-document est structurellement
|
||||
impossible.
|
||||
|
||||
### La conséquence à connaître : le `:v:` est un pseudonyme stable
|
||||
|
||||
**Tous les documents d'une même personne dans son store protected portent le MÊME
|
||||
`:v:`** = `outer(protected_store_id)`. Donc une référence cap-less — précisément
|
||||
celle qu'on utilise pour « nommer sans donner à lire » — **expose l'appartenance
|
||||
au store**, c'est-à-dire un **identifiant pseudonyme stable et permanent de la
|
||||
personne**. Le store_id lui-même ne fuit pas (BLAKE3 non inversible), donc ça ne
|
||||
dit pas *qui* ; mais c'est un **handle constant**, le même partout et pour
|
||||
toujours, corrélable par quiconque collecte des références cap-less.
|
||||
|
||||
**Le couplage qui en résulte, et qui contraint tout modèle de présence anonyme** :
|
||||
ce même `:v:` est *simultanément* (a) ce qui permet de **dédupliquer** des
|
||||
références sans les lire — deux références de même `:v:` viennent de la même
|
||||
personne — et (b) ce qui permet de **tracer** cette personne d'un contexte à
|
||||
l'autre. **C'est le même bit d'information.** On ne peut pas obtenir la dédup sans
|
||||
concéder le traçage, ni supprimer le traçage sans perdre la dédup — sauf à changer
|
||||
le découpage en stores, ce qui déplace le curseur mais ne supprime pas l'arbitrage.
|
||||
|
||||
*Nuances.* Le `:v:` du NURI est l'overlay **outer**, alors que le trafic
|
||||
client↔broker et le stockage local utilisent l'**inner** — valeur différente, mais
|
||||
tirée du store elle aussi, donc la propriété tient dans les deux cas. Un store
|
||||
`Dialog` renvoie un `Inner`, toujours store-scopé.
|
||||
|
||||
INFÉRÉ : un détenteur **sans clé** peut vraisemblablement **récupérer les blocs
|
||||
chiffrés** (avec l'overlay, toujours cap-less) → vérifier l'**existence** d'un doc
|
||||
|
||||
Reference in New Issue
Block a user