fix(@data): round-trip the seed/read path against the real broker
Multiple compounding defects kept the connected @data read at 0 entities: - writeEntity/updateEntityField and registration helpers wrote into an explicit GRAPH <plainNuri> named graph, invisible to the anchored default-graph read (read-model.readDoc) after the read switched to per-doc anchored. Drop the wrapper so writes land in the repo's default graph (matches the read). - Seed entities are now owned by the CURRENT account, so protected seed docs (user profiles) pass the per-document ReadCap gate and round-trip. - Suppress the double seed (explicit loadTestData + 3s dev auto-seed) and add a re-list signal so freshly-seeded protected docs enter the read set. - @data step awaits the seed result and waits for events AND users > 0. Documents the anchored-default-graph write pitfall in rule_document-per-entity. Validated: connexion-nextgraph.feature @data = 4 scenarios / 13 steps green. NB: the shared test wallet's private store bloats across runs and makes anchored queries hang (>15s); a fresh .playwright-profile restores ~1.5s — durable wallet hygiene is a follow-up. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -310,14 +310,16 @@ function ConnectedHarness() {
|
||||
const protectedDocs = await reg.listEntityDocs('protected');
|
||||
let total = 0;
|
||||
for (const g of protectedDocs) {
|
||||
// Anchored default-graph (no `GRAPH` clause): participations are
|
||||
// written by writeEntity into each doc's DEFAULT graph, so the
|
||||
// authoritative count must read that same graph (matches the app's
|
||||
// registration.ts countParticipations after the graph-mismatch fix).
|
||||
const query = `
|
||||
SELECT (COUNT(DISTINCT ?s) AS ?n) WHERE {
|
||||
GRAPH <${g}> {
|
||||
?s a <http://festipod.org/Participation> ;
|
||||
<http://festipod.org/event> ?event ;
|
||||
<http://festipod.org/user> ?user .
|
||||
FILTER( STR(?event) = "${esc(eventId)}" && STR(?user) = "${esc(userId)}" )
|
||||
}
|
||||
?s a <http://festipod.org/Participation> ;
|
||||
<http://festipod.org/event> ?event ;
|
||||
<http://festipod.org/user> ?user .
|
||||
FILTER( STR(?event) = "${esc(eventId)}" && STR(?user) = "${esc(userId)}" )
|
||||
}`;
|
||||
const result: any = await docs.sparqlQuery(session.session_id, query, undefined, g);
|
||||
const rows = Array.isArray(result) ? result : result?.results?.bindings ?? [];
|
||||
@@ -569,15 +571,20 @@ function ConnectedHarness() {
|
||||
const reg = await import('../utils/storeRegistry');
|
||||
const disc = await import('../data/discovery');
|
||||
reg.resetRegistryCache();
|
||||
console.error('[PROBE] publishPublicEventAs: ensureAccount(publisher)…');
|
||||
await reg.ensureAccount(publisher);
|
||||
console.error('[PROBE] publishPublicEventAs: createEntityDoc(publisher,public)…');
|
||||
const doc = await reg.createEntityDoc(publisher, 'public');
|
||||
console.error('[PROBE] publishPublicEventAs: publisher doc=' + doc);
|
||||
// Deposit AS the current identity: the inbox guard binds `from` to the
|
||||
// CURRENT user and rejects a spoofed `from`. So make the publisher the
|
||||
// current identity (its normalized-username key = the cap-owner key),
|
||||
// then submit WITHOUT a spoofed explicit `from` — the SDK stamps the
|
||||
// current identity itself (anonymous submission also allowed).
|
||||
setCurrentUser(normalizeUsername(publisher));
|
||||
console.error('[PROBE] publishPublicEventAs: submitEventToIndex…');
|
||||
await disc.submitEventToIndex({ doc, id: doc, title }, getCurrentUser());
|
||||
console.error('[PROBE] publishPublicEventAs: submitted OK');
|
||||
return { doc };
|
||||
},
|
||||
async discoverPublicEventsAs(discoverer: string) {
|
||||
|
||||
Reference in New Issue
Block a user