docs: consigner l'écart sur l'inbox choisie par share

`inbox.share` dépose toujours sur l'inbox PROTÉGÉE du destinataire. En amont le
choix n'est pas fixe : un enregistrement de contact prend son inbox du PROFIL par
lequel la personne a été atteinte — `a_or_b = if details.profile.is_public()
{ "site" } else { "protected" }` (`inbox_processor.rs:787`, écrit `ng:site_inbox`
ou `ng:protected_inbox` en `:823-824`).

Mineur aujourd'hui, mais ça aplatit une distinction du modèle, et ce sera faux le
jour où une application partagera avec quelqu'un rencontré par son profil public.

Consigné plutôt que corrigé : le correctif demande une notion que rien n'a
établi ici. Ce qui EST vérifié se limite à un wallet qui contient des `sites`, un
`SiteV0` avec `id: PubKey`, `name`, `site_type` et trois stores. L'enum
`Identity`, qui nommerait le reste, est entièrement COMMENTÉ en amont
(`engine/repo/src/types.rs:586-595`) — il n'y a donc aucun modèle de profil à
lire, et rien à supposer.

Rappelé au passage, parce que la question s'est posée : le store privé n'a
aucune inbox — `new_store_default` n'en attache une que `if !private` — d'où
`InboxScope`, qui rend « l'inbox privée » inécrivable plutôt que simplement vide.
This commit is contained in:
Sylvain Duchesne
2026-08-06 16:25:33 +02:00
parent cb56f91b5e
commit 94173fd3d3
2 changed files with 25 additions and 1 deletions
+23 -1
View File
@@ -296,7 +296,29 @@ export async function share(doc: NuriLike, toUser: string): Promise<void> {
`for it. A cap is looked up in what you hold, or it was delivered to you: ${JSON.stringify(target)}`,
);
}
// Protected, because directed sharing is not a public announcement.
// ── KNOWN DIVERGENCE: the protected inbox is hard-coded here ──────────────
// Upstream the choice is not fixed. A contact record picks its inbox from the PROFILE
// through which the person was reached: `a_or_b = if details.profile.is_public()
// { "site" } else { "protected" }` (`engine/verifier/src/inbox_processor.rs:787`,
// written as `ng:site_inbox` vs `ng:protected_inbox` at `:823-824`). Reach someone by
// their public profile and the deposit goes to their public store's inbox; by their
// protected profile, to the protected one.
//
// This library has no notion of "the profile by which I know this person", so it
// always uses the protected one. Minor today — a consumer names a user and gets one
// answer — but it flattens a distinction the model makes, and the day an application
// shares with someone met through a public profile, this picks the wrong inbox.
//
// Not fixable in isolation: it needs a notion this library does not have, and about
// which nothing has been established here. What IS verified: a wallet holds `sites`,
// a `SiteV0` has an `id: PubKey`, a `name`, a `site_type` (Individual | Org) and three
// stores (`engine/verifier/src/site.rs:23-40`); the `Identity` enum that would name
// the rest is entirely COMMENTED OUT upstream (`engine/repo/src/types.rs:586-595`).
// Do not build on an assumed profile model — there is none to read yet.
//
// (The private store has no inbox at all — `new_store_default` attaches one only
// `if !private`, `verifier.rs:2994` — hence `InboxScope`, which makes "the private
// inbox" unwritable rather than merely empty.)
await post(await userInbox(toUser, "protected"), { payload: { kind: LINK_KIND, cap } });
}