88efe4fea4962944dd399d0777e8c28c47a90dd6
3 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
5a7009bd75 |
fix(inbox): une inbox appartient à un document, jamais à plusieurs
Retour sur l'adresse par défaut livrée en
|
||
|
|
8a382f29f8 |
feat(inbox): l'inbox d'un document est adressable par tout détenteur
Répond au brief 2026-08-03 remonté depuis le consommateur. `documentInbox(doc)` répondait « quelle inbox est-ce que MOI je connais pour ce document » et en créait une quand la réponse était « aucune » : un tiers n'atteignait jamais l'inbox du propriétaire, il en obtenait une à lui, que personne ne lit, et son dépôt disparaissait sans erreur. C'est l'acte central du consommateur — s'inscrire à l'événement d'un autre — qui était silencieusement perdu. Lire une inbox et savoir où y déposer sont deux actes opposés, avec des publics opposés. Ils sont désormais deux fonctions : - `openDocumentInbox(doc)` — le PROPRIÉTAIRE ouvre une inbox dédiée. Refuse sur la PROPRIÉTÉ (lue depuis les branches Store), pas sur la possession du cap : un cap se reçoit, et un destinataire ne doit pas pouvoir rediriger vers lui les dépôts destinés au propriétaire. - `documentInboxAddress(doc)` — n'importe quel détenteur trouve où déposer. Ne crée jamais rien. L'adresse est publiée dès la CRÉATION, sur la branche Header émulée du document — un sujet réservé à l'intérieur du document, donc lisible par qui détient le document. Publier seulement le jour où le propriétaire ouvre une inbox dédiée laisserait une fenêtre pendant laquelle un tiers lit le document, ne trouve aucune adresse, et ne peut pas joindre le propriétaire du tout. Sur le coût mesuré par le brief (9m37 → 21m30) : il venait de la création d'un DOCUMENT supplémentaire par document. L'adresse publiée pointe vers l'inbox propre du propriétaire, qui existe déjà et s'amortit sur tous ses documents ; la création grandit d'un triple, pas d'un document. Le dépôt porte le document concerné, donc le propriétaire matérialise toujours par document. La forme « dérivable » du brief n'était pas disponible : notre inbox est un document, et un NURI dérivé nommerait un repo que `doc_create` n'a jamais créé. Le tout reflète la séparation d'amont : un déposant scelle avec la clé PUBLIQUE de l'inbox et n'a besoin de rien d'autre, seul le propriétaire détient la moitié privée — une adresse est donc publique par nature. `src/machinery.ts` : l'espace de noms `urn:ng-eventually:` que la bibliothèque se réserve, et le prédicat que le chemin de lecture utilise. La branche Header est le premier compartiment logé dans un document que le consommateur lit ; `read-model` écarte désormais tout sujet de cet espace, par SUJET et non par prédicat — ce qui couvre toutes les branches émulées, présentes et futures. Question ouverte du brief, tranchée : « une inbox de document adressable par tout détenteur » est une invention de cette bibliothèque, pas de l'amont — aucun document n'y a d'inbox, ni le store privé. Ce qui EST vérifié, c'est la forme qui rend l'anticipation défendable : `AddInboxCapV0` est clé par `repo_id`. Tests : le test qui validait « n'importe qui dépose » passait le NURI d'inbox au déposant par une variable du test — chemin qu'aucune app n'a. Réécrit avec les deux acteurs cloisonnés : le déposant reçoit le lien du document, qui est la seule chose qui circule dans ce modèle, et doit trouver l'adresse lui-même. Le fake `ng` gagne le SELECT de la branche Header et le `DELETE WHERE` (sans quoi un remplacement devenait une accumulation, précisément le bug qu'il évite). 157 tests unitaires, e2e 40/40 contre le broker en ligne. |
||
|
|
33751388fe |
Ask that a document's inbox be addressable by anyone holding the document
`documentInbox(doc)` answers "which inbox do I know for this document?" and mints a fresh one when the answer is none. A third party therefore never reaches the owner's inbox: they get one of their own, the owner never reads it, and the deposit vanishes with no error. That breaks the consumer's central act — signing up to someone else's event — and it blocks the directory document that has to replace discovery, since creators must deposit into a document they do not own. The consumer tried solving it on its side: resolve the address once at creation and publish it on the public document, so participants read it instead of deriving it. It works, and it is still the wrong place. It puts a technical address into a domain shape; it doubles document creation on every event, since resolving an inbox creates one (the @data suite went from 9m37 to 21m30, with sign-up scenarios timing out during setup on a FRESH profile — not wallet bloat); and the library already claims this job, having stated when per-document inboxes landed that draining them "is the library's job, not the app's". Addressing is the other half of that same job. The app-side change is reverted. No shape is prescribed here. Deriving the address from the document would cost nothing and match how the rest of the model works — an overlay is derived, a keyring is looked up, nothing is handed over out of band — with the read guard keeping the asymmetry where it belongs. Publishing it library-side would work too and leaves room to make it lazy. One question decides where this note ultimately belongs: is "a document has an inbox addressable by any holder" part of NextGraph's target model, or this library's own invention? Upstream, it is emulation to align; otherwise it is a design decision to take deliberately. |