3dfc2310050380c98ea0bb6ffdce193266fb2c04
53 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
f378c71739 |
docs: sept affirmations sur NextGraph requalifiées à la source
Lot F de la revue adverse. Chaque affirmation relue dans `nextgraph-rs` par symbole avant
d'être réécrite ; aucune ne s'est révélée exacte.
- `AddLink` / `RemoveLink` / `RepoLinkV0` étaient présentés comme **implémentés**. Leurs
arms de vérificateur sont des `Ok(())`, là où celui d'`AddRepo` fait un vrai travail, et
rien ne les construit. Le tableau dit désormais « déclaré, stubbé », et la conclusion qui
en déduisait « le registre existe, seule la livraison manque » est corrigée : **les deux
bouts** sont déclarés-et-stubbés.
- La table `inboxes` était dite « reconstruite vide à chaque session » — elle est
repeuplée au chargement, et la clé privée d'inbox est persistée par repo. L'argument de
sécurité qui s'appuyait dessus repose maintenant sur le bon motif : la table est **par
vérificateur**, pas éphémère.
- La citation de « `doc_create` laisse `inbox: None` » pointait un constructeur réservé aux
tests ; re-ciblée sur le chemin de production.
- `ExtObjectGet` était dit « le seul » primitif accessible à un non-membre et exigeant les
clés : il y en a trois, et sa structure n'a aucun champ de clé.
- L'en-tête de `public-store.ts` était marqué **VERIFIED** alors qu'il repose sur un
commentaire de doc, et la condition qu'il citait (« si les brokers pairs l'autorisent »)
disparaissait de la conclusion. Requalifié en **pari**, condition rétablie.
- Deux sur-restrictions corrigées (ce qu'écrit le traitement d'un `ContactDetails`, et le
prétendu « miroir 1:1 » de `NuriV0`, qui a dix champs).
**Sur la grammaire du ReadCap, une correction de MA correction.** J'avais écrit que la
forme `{target}:r:{cap}` était notre invention. Faux : le segment `r:` et son encodage sont
ceux d'amont, et l'auteur de NextGraph l'a énoncé. Ce qui est établi est plus étroit —
aucun parseur amont n'accepte aujourd'hui un NURI de repo qui le porte, et le segment est
produit comme valeur de champ. J'avais conclu d'une implémentation absente à ce que la
cible ferait, ce que la doctrine du projet interdit nommément. Seule « P1b remplace la
valeur, pas la forme » est corrigée, requalifiée en **pari**.
**Et la surface ne publie plus de type que personne n'utilise.** `export * from
"./model/types"` publiait huit types en bloc ; c'est une liste nommée de six. `ReadCap`
sort — aucune signature publiée ne le prend ni ne le rend, seules deux fonctions privées
de `inbox.ts` s'en servent — et `InboxScope` aussi. Un type n'est publié que si une
signature publiée l'utilise.
197 tests, 0 échec ; les trois typechecks propres ; `lint` sans erreur.
|
||
|
|
cdc09a1a1d |
refactor(api): l'application ne nomme plus son identité — elle l'apprend
Lot C de la revue adverse. Cinq corrections, dont une qui change la forme de la surface. **L'application ne pouvait pas obtenir son identité par l'API.** `ensureIdentity()` rendait `void`, `getCurrentUser` n'est plus publié — et pourtant `createEntityDoc(id, …)` et `listMyEntityDocs(id, …)` l'exigeaient. L'app d'exemple s'en sortait en lisant `localStorage["ng-eventually:identity"]` et le paramètre `?ng-id`, deux constantes PRIVÉES du portail d'accès. Une frontière qu'aucun consommateur ne devrait voir, et encore moins dont il devrait dépendre. Vérifié au niveau 2 avant de trancher : `session_start(wallet_name, user_id)` prend l'identité — donc en amont l'application la DÉTIENT, elle la tient du portefeuille qu'elle a ouvert. Ici c'est le portail qui la choisit, donc c'est au portail de la rendre. Deux changements, tous deux vers la cible : - `ensureIdentity()` rend l'identité qu'il a établie ; - `createEntityDoc(scope)`, `listMyEntityDocs(scope)`, `resolveWriteGraph(scope)` perdent leur paramètre d'identité. En amont `doc_create(session_id, …)` ne porte aucun utilisateur : une session EST celle d'un utilisateur. Passer la sienne à chaque appel de placement était un geste sans successeur. L'application garde l'identité pour l'afficher, et ne la passe plus à rien. **`inbox.share` provisionnait un destinataire inexistant.** Une faute de frappe créait les trois stores et l'inbox de ce nom, et la clé atterrissait où personne ne regarde — sans la moindre erreur. En amont on ne peut pas viser un nom qu'on invente : un dépôt est scellé vers une clé d'inbox qui vous est parvenue par un contact entrant. Refuser est fidèle ; provisionner était l'invention. **`createEntityDoc` avalait l'échec de ses deux écritures** et rendait quand même une référence — le document n'était dans aucun store, donc la session suivante ne le listait pas et sa lecture rendait vide, en silence. Il lève maintenant, comme `doc_create` en amont propage les siennes. **Deux entrées prenaient `Nuri` au lieu de `NuriLike`** (`inbox.watch`, `openDocumentInbox`), ce qui contredisait la raison même pour laquelle aucune garde de type n'est publiée. Et **deux messages d'erreur nommaient des symboles retirés** (`storeRegistry.documentInboxAddress`, `setCurrentUser`) : une erreur qui envoie vers une fonction inexistante est pire qu'une erreur muette. Contrat d'API et feuille `contract_sdk-surface` mis à jour ; `readForDocument` et le refus de `share` obtiennent enfin leur règle en §9. 189 tests unitaires, e2e 40/40 et applicatif 12/12. |
||
|
|
30f6263db5 |
docs(concept): le contrat entre le polyfill et l'application qui l'utilise
Amorce le système `concept` dans ce dépôt et ouvre `app-contract` — la frontière entre cette bibliothèque et les applications qui la consomment. C'est un contrat **inter-dépôts** et ce dépôt en est le FOURNISSEUR : les applications vivent ailleurs et tireront `sdk-surface` d'ici. D'où le type `contract_`, ses cinq sections obligatoires, et l'inscription dans `.project/contracts.yaml` — c'est l'inscription qui publie. Trois feuilles : - **`contract_sdk-surface`** — l'engagement, écrit du point de vue de l'appelant. Ce qu'il peut tenir pour acquis : permissif en entrée et précis en sortie ; toute référence rendue est NUE, aucun appel ne rend jamais de clé ; lire est la possession, écrire est la propriété ; donner à lire est un seul acte et le destinataire n'appelle rien ; un dépôt s'adresse à une inbox, jamais à un document ; `ensureIdentity()` est toute la connexion ; et `configure` est le seul appel qu'il supprimera. Ce qu'il ne doit PAS tenir pour acquis, dit aussi crûment : aucune confidentialité, rien de « par lecteur » sur un document public, aucune révocation, aucune écriture déléguée, et les références ne voyagent que dans un déploiement. - **`rule_would-the-caller-unlearn-it`** — le test qui décide de tout : est-ce que ceci ferait apprendre à l'appelant quelque chose qu'il devra DÉSAPPRENDRE ? Avec les deux tells que la revue de ces jours-ci a rendus concrets : une exception nommée cesse d'en être une dès qu'on la publie, et un symbole gardé parce qu'il était là n'est pas une décision. - **`knowledge_what-an-app-deletes-at-migration`** — les deux destins d'un symbole publié, le cas intermédiaire d'`ensureIdentity` (substance jetée, site d'appel conservé), et le fait que la liste de suppression n'est plus portée par un chemin d'import depuis la fusion des entrées : une garantie mécanique remplacée par une garantie documentaire, dont seule la moitié est tenue par un test. Le vocabulaire du concept fixe trois termes que ce projet a déjà payé cher : `reference` (jamais « lien »), `ReadCap`, `polyfill-era`. `lint` est conformant. Reste à décider : ce dépôt n'a pas de `CLAUDE.md` racine, donc l'`AGENTS.md` généré n'est chargé nulle part. |