fix(caps): créer un document en donne le cap, + corriger 9 faits NextGraph
Le trou trouvé par l'e2e contre le broker en ligne : `docs.docCreate` ne
déposait aucun cap pour le créateur, donc un consommateur pouvait créer un
document par la primitive publique puis se voir refuser sa lecture et son
écriture. En amont c'est impossible — `doc_create` commite
`AddRepo { read_cap }` sur la branche Store du store, et le créateur le détient
dès le premier instant. Délibérément non répliqué dans `physical.ts` : les
documents du shim n'appartiennent à aucun utilisateur virtuel, et
`store-registry` classe leurs caps là où il sait à qui ils sont.
e2e : 22 passés / 8 échoués → 39 / 0. Les autres échecs venaient du harnais,
qui agissait comme une seconde identité sans l'établir, ou lisait un document
quelconque comme une inbox. Un run e2e contre un wallet persistant exige une
identité FRAÎCHE par run : `walletInbox(id)` rend l'inbox stable pour son
propriétaire — c'est son intérêt — donc un id fixe accumule les dépôts des runs
précédents (vert au 2e run, rouge au 3e, à code inchangé).
Revue adverse de la documentation, 9 défauts, tous vérifiés à la source avant
correction :
- « chaque document a une inbox native » est FAUX. Seuls les repos de store
public et protected en ont une (`site.rs:128,149`) ; `new_store_default` n'en
pose que `if !private` et `doc_create` laisse `inbox: None`. Le store privé
n'en a pas non plus. Ce que le code fait est donc une ANTICIPATION — assumée
et notée comme telle dans `documentInbox`, le brief et l'ADR discovery. Ce qui
est vérifié, c'est la FORME : `AddInboxCapV0` est clé par `repo_id`.
- `InboxMsgContent::Link` est une variante unit sans charge utile : l'inbox ne
transporte aucun ReadCap. `shareCap` était juste et le reste ; ses citations
sont complétées aux deux bouts (émetteur `unimplemented!()`, récepteur qui
ignore `details.read_cap`).
- les 3 stores appartiennent au user (`SiteV0`), pas au wallet ;
- le TODO `OpenRepo` ne concerne pas la lecture cross-wallet — il est dans
`open_branch_`, après `RepoNotFound` ; charger par cap, c'est
`load_repo_from_read_cap` ;
- la liste des méthodes JS était un sous-ensemble présenté comme la surface
(77 exportées) ;
- `outbox-log.ts` n'enregistre rien : il inspecte l'outbox du SDK ;
- l'ADR private-store-nuri-scope citait `orm_start_graph` au présent, remplacé
par `ensureRepoOpen` ;
- l'incident write-loss plaçait `disconnections_sender.send` dans `broker.rs` ;
- la section « Apps & services » n'a aucune citation et rien ne lui correspond
dans le moteur : marquée à re-confirmer, pas à citer comme vérifiée.
Aussi : `fileOwnCaps` n'existe plus (`holdOwnCap` / `readStoreCaps` /
`fileOwnStructure`) — pointeur mort corrigé dans `caps.ts`.
This commit is contained in:
@@ -224,7 +224,9 @@ async function main(): Promise<void> {
|
||||
// ── inbox ───────────────────────────────────────────────────────────────
|
||||
console.log("\n── inbox ──");
|
||||
await step("inbox post → read round-trip", async () => {
|
||||
const r = await sdk<any>(frame, "inboxPostRead", { k: "a" }, { k: "b" });
|
||||
// Fresh user per run: an inbox is stable for its owner, so a reused id would
|
||||
// read back the previous runs' deposits too (the wallet persists).
|
||||
const r = await sdk<any>(frame, "inboxPostRead", "@inbox-user-" + Date.now(), { k: "a" }, { k: "b" });
|
||||
const payloads = (r.deposits || []).map((d: any) => JSON.stringify(d.payload));
|
||||
check(
|
||||
"post then read returns both deposits (sorted)",
|
||||
@@ -233,7 +235,7 @@ async function main(): Promise<void> {
|
||||
);
|
||||
});
|
||||
await step("inbox watch fires on deposit", async () => {
|
||||
await sdk(frame, "inboxWatchStart");
|
||||
await sdk(frame, "inboxWatchStart", "@watcher-" + Date.now());
|
||||
await frame.waitForFunction(() => (window as any).__sdk.inboxWatchState().fires >= 1, { timeout: 20000 });
|
||||
const base = await sdkGet<any>(frame, "inboxWatchState");
|
||||
await sdk(frame, "inboxWatchDeposit", { landed: true });
|
||||
@@ -329,7 +331,7 @@ async function main(): Promise<void> {
|
||||
);
|
||||
});
|
||||
await step("shareCap: a cap delivered to an inbox reveals the doc", async () => {
|
||||
const r = await sdk<any>(frame, "capsShareCap");
|
||||
const r = await sdk<any>(frame, "capsShareCap", "@friend-" + Date.now());
|
||||
check(
|
||||
"shareCap → inbox processed → the shared doc becomes readable, and the delivery is not surfaced",
|
||||
r.before === 0 && r.after === 1 && r.surfacedDeposits === 0,
|
||||
|
||||
Reference in New Issue
Block a user