feat: un dépôt est traité vingt secondes après, sans attendre son destinataire
Un dépôt attendait la prochaine connexion de son destinataire — potentiellement des heures. Un vrai NextGraph aura un service qui traite les inbox en continu ; il n'existe pas. On l'émule : après une écriture dans une inbox, une échéance unique de vingt secondes draine l'inbox DE LA CIBLE. C'est une usurpation d'identité, possible seulement parce qu'un portefeuille partagé détient toutes les identités virtuelles. Elle est acceptable parce que l'application n'apprend rien de faux : elle observe que les dépôts finissent par converger, ce qui restera vrai avec un vrai service. Ce qui ne doit pas fuir, c'est le mécanisme. Trois gardes, tenues par du code et non par des consignes. Rien n'atteint la surface publiée : les exports sont épinglés par un test, et publier ceci reviendrait à publier un appel qui traite l'inbox d'autrui — après quoi il ne resterait rien du modèle de confidentialité. Le drainage agit avec un détenteur EXPLICITE, jamais l'identité ambiante. Le propriétaire vient d'un enregistrement de routage (shim:inboxOwner), et cet identifiant est passé à chaque étape. C'était le vrai danger : readLinks et myInboxes demandent getCurrentUser() au moment où elles s'exécutent, donc un drainage lancé pendant la session d'Alice aurait classé les capacités de Bob chez elle. Le test l'épingle — après le drainage, Alice n'a aucune capacité sur le document concerné, et les deux Links sont bien chez Bob, durablement. Et les échecs remontent au journal d'accès au lieu de disparaître. Une boucle différée qui avale ses erreurs, c'est la famille retirée en8c8ade7ete32b6d0. Coalescence : une seule échéance en attente par cible, et deux drainages d'une même inbox ne se chevauchent jamais — processInbox écrit ce qu'il applique. Limite assumée : si la page disparaît avant l'échéance, le dépôt attend la prochaine connexion. C'est le comportement honnête d'une émulation qui tient la place d'un service absent.
This commit is contained in:
@@ -270,6 +270,22 @@ export class CapRegistry {
|
||||
return this.heldCaps().get(targetOf(nuri));
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the NAMED holder hold `nuri`'s cap? The reading counterpart of {@link learnFor},
|
||||
* and it exists for the same caller: work decided for one holder that runs while ANOTHER
|
||||
* one is connected — the emulated inbox processor
|
||||
* (`emulated-verifier/inbox-processor.ts`), which drains an inbox on behalf of its owner
|
||||
* during someone else's session. Asking `capFor` there would consult the connected
|
||||
* identity's ring, which is not the ring the question is about.
|
||||
*
|
||||
* Reads without creating a ring, unlike {@link heldCaps}: asking about a holder must not
|
||||
* file one. Still no principal parameter in the model's sense — the question is "does
|
||||
* THIS ring hold the key", never "may principal P read D".
|
||||
*/
|
||||
capForHolder(key: string, nuri: Nuri): ReadCap | undefined {
|
||||
return this.heldByHolder.get(key)?.get(targetOf(nuri));
|
||||
}
|
||||
|
||||
// --- publication (the public store) -------------------------------------
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user