Commit Graph

5 Commits

Author SHA1 Message Date
Sylvain Duchesne 8764daff4f docs: corriger la rotation de clé et poser le principe du store public
Deux corrections de direction, données par le PO — et les deux viennent de la
même erreur de méthode : avoir lu l'ÉTAT COURANT du source comme s'il donnait
l'INTENTION. C'est précisément ce que ce brief met en garde de faire.

1. Rotation de clé. La spec disait « qui n'est pas resté abonné perd l'accès »
   et demandait d'exposer une obligation d'abonnement au consommateur. Faux
   comme cible : quand une clé tourne, la nouvelle est envoyée dans l'inbox des
   ayants droit, et cette inbox est traitée automatiquement à la connexion
   suivante d'un client. L'accès n'est pas perdu, il est différé — cohérent avec
   le local-first. Donc rien à implémenter côté consommateur, et la re-livraison
   emprunte le même canal que la livraison initiale : le mécanisme de partage
   couvre les deux sans cas particulier.

2. Store public. Principe à exposer tel quel : un élément du store public est
   public — qui a l'URL lit le contenu — mais PAS récursivement. Un contenu
   public peut référencer du contenu privé sans donner accès au référencé. C'est
   la non-récursivité qui porte la valeur : elle permet un objet public pointant
   vers de l'identité privée, le cas exact du consommateur. NextGraph s'oriente
   par ailleurs vers un non-chiffrement du contenu public (données toujours
   signées) : détail d'implémentation dont la surface ne doit pas dépendre. Si le
   store public ne se comporte pas comme le principe le décrit, c'est le polyfill
   qui s'adapte, pas le consommateur.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014GbGgNEHRejVKoREvFuDFg
2026-07-27 17:05:36 +02:00
Sylvain Duchesne 60a9fd3ede docs: réécrire P1a après double revue adverse, corriger le verdict Q1 sur-lu
Deux adversaires à mandats disjoints (alignement NextGraph / économie
conceptuelle). Résultat : P1a fond de 8 notions nouvelles à 2, et un fait que
j'avais consigné comme VÉRIFIÉ était sur-lu.

CORRECTION DE FOND — le fetch keyless n'est PAS constructible. Le spike P0
concluait « Q1 OUI partiel, seul garde : l'overlay ». Il s'arrêtait au contrôle
d'accès sans regarder l'ADRESSAGE : aucune commande d'existence au niveau SDK ;
la seule sonde est interne au crate, exige des BlockId ET un repo chargé, et vise
l'overlay inner dérivé du secret de lecture. Une référence cap-less porte un
RepoId et l'overlay outer — ni BlockId, ni le bon overlay. L'adressage
présuppose le cap. Note corrigée sur place (pas empilée), avec la leçon
transposable : vérifier qu'une garde laisse passer ne prouve pas qu'une
opération est atteignable — encore faut-il pouvoir NOMMER ce qu'on demande.

P1a réécrite :
- UN seul type nouveau, `ReadCap`, le nom de l'amont. `Nuri` reste ce qu'il est
  déjà (~90 usages) : la forme cap-less. Les types de marque disparaissent — le
  SDK réel prend `nuri: String` et enforce au RUNTIME par la crypto ; une
  garantie de compilation est un concept que NextGraph n'a pas, et un
  consommateur qui typerait tout devrait dé-typer plus tard.
- `capFor(nuri) → ReadCap | undefined` : le trousseau. Comble un trou fatal du
  premier jet — `doc_create` renvoie un NURI cap-less, donc l'invariant « on ne
  va jamais d'une référence nue à un cap » empêchait le créateur d'obtenir le cap
  de son propre document. Le trousseau existe déjà : la branche de store, où
  chaque création commite AddRepo{read_cap}. En amont c'est le wallet.
- `shareCap(cap, toInbox)` : on partage UN DOCUMENT, à une ou plusieurs inboxes.
  Pas le store — donner un cap de store livrerait tout son contenu présent et
  futur. Les caps reçus arrivent comme dépôts d'inbox, consommés par le
  inbox.watch existant (ce qui règle le point 7 de la revue adverse).
- Durabilité : ne PAS la promettre. Verbatim amont, les caps sont « not durable »
  et qui ne reste pas abonné perd l'accès ; PermaCap est un TODO. La surface doit
  exposer l'obligation d'abonnement, sinon le consommateur retient des caps morts.
- `PrincipalId` sort de la surface caps : n'existe pas en amont, et le brief le
  supprimait de canRead en le qualifiant d'inversion ACL avant de le réintroduire
  dans sealCapTo. On adresse des inboxes, comme inbox.post le fait déjà.
- Section 0 conservant les erreurs du premier jet : elles sont instructives.
- Exception publique actée : un lien de repo public n'a PAS de read_cap (il se
  télécharge depuis l'outer overlay) — pour du public, « référence nue → contenu »
  est bien la forme cible.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014GbGgNEHRejVKoREvFuDFg
2026-07-27 16:08:02 +02:00
Sylvain Duchesne d7e0ee6a4b docs(brief): spécifier P1a (la surface) et corriger l'inventaire des contournements
Découpage de P1 en deux natures de travail : P1a = la FORME exposée aux
consommateurs, P1b = l'ENFORCEMENT. Seul P1a bloque Festipod, puisque l'app doit
être écrite comme si NextGraph était fini. Après P1a la forme est juste et
l'isolation reste fausse — le brief le dit explicitement pour qu'on n'affirme
rien d'anonyme avant P1b.

P1a spécifié :
- Types DocRef / DocCap distincts À LA COMPILATION (aujourd'hui `Nuri = string`,
  aucun parseur, aucune notion de segment de clé). L'invariant central : AUCUNE
  fonction ne va de DocRef vers DocCap — on n'obtient pas un cap en le demandant,
  seulement en le recevant. Le compilateur refuse alors de lire depuis un
  identifiant nu, et le consommateur ne PEUT PLUS écrire le modèle mental faux.
- resolveCapLess(ref) → { exists }, jamais de contenu et jamais d'état `deleted`
  (vérifié : la cible ne pourra pas l'offrir).
- sealCapTo(cap, recipient) durable + receivedCaps(), qui remplacent grantRead.
  Trois deltas réels vs l'ACL : durabilité, livraison-chez-le-destinataire,
  re-partage par le détenteur. C'est ce qui fait disparaître declareConnections.
- Table de ce qui disparaît : le paramètre `principal` de canRead EST l'inversion
  ACL ; resetCaps doit BASCULER de trousseau, pas effacer, sinon la durabilité
  est un mensonge.
- Test de recette naturel : watch-shape moissonne aujourd'hui toute chaîne
  `did🆖` et la replie dans l'ensemble LU — sémantique exactement inversée.
  Avec les types, elle ne peut plus qu'être résolue en existence. Vérifiable sans
  une ligne de crypto.

Corrigé aussi : l'inventaire des contournements était écrit beaucoup trop
doucement. Cartographie vérifiée — seuls 4 sites consultent les caps ; l'inbox
entière, store-registry (racine de confiance compte→NURI), discovery.readIndex,
subscribe et open-repo rendent de la donnée sans garde. Et le garde d'ÉCRITURE
est déjà mort-né : docs contourne ng-proxy par conception et tous les écrivains
internes passent par docs — grantWrite/canWrite ne se déclenchent jamais.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014GbGgNEHRejVKoREvFuDFg
2026-07-27 14:48:48 +02:00
Sylvain Duchesne ead5aececf 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
2026-07-27 12:07:24 +02:00
Sylvain Duchesne 1791c31f42 docs: vision du polyfill (shape-fidelity), modèle ReadCap/NURI réel, brief caps
vision.md — la charte : le polyfill n'est PAS une couche de sécurité (wallet
partagé + pas de crypto = insécurité ACCEPTÉE) ; seul objectif = exposer la
BONNE FORME des primitives futures pour que les consommateurs n'aient rien à
réécrire. Invariant tenu par une simulation crypto légère : un `did` nu (sans
ReadCap) ne permet PAS de lire ; un NURI avec ReadCap est suffisant et requis.

readcap-and-nuri-model.md — le vrai modèle, VÉRIFIÉ par lecture de
`nextgraph-rs` : ReadCap = ObjectRef {id BLAKE3, clé ChaCha20} = possession de
clé, PAS une ACL ; grant = sceller la clé à l'inbox du destinataire ;
révocation = re-key grossier et non-rétroactif ; grammaire NURI cap-less vs
cap-porteur (le segment `:k:` est le discriminant) ; table des divergences avec
l'émulation `caps.ts` (aujourd'hui une ACL — l'inversion exacte).

briefs/2026-07-20-caps-emulation-alignment.md — le chantier d'alignement :
spike P0 keyless-resolve (verdicts vérifiés : existence sans clé OUI,
détection de suppression sans clé NON, confidentialité OUI), puis P1 cap-less
vs cap-porteur, P2 possession, P3 re-key, P4 migration d'API. Inclut la revue
adverse (WriteCap = membership et non possession ; sans crypto la privacy de
lecture n'est pas applicable ; migration = re-architecture consommateur).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014GbGgNEHRejVKoREvFuDFg
2026-07-27 11:30:33 +02:00