The previous commit treated this package like the polyfill: a provider whose
source is off limits, with the unknowns raised as questions. That was the wrong
regime. The no-read rule attaches to a provider that publishes an engagement —
this one publishes nothing at all, and for that case the protocol has a bounded
reconstruction, made once at adoption time and pinned. So the two questions are
answered here rather than asked, and one of them turned out to be about the Pod
rather than about the providers, which is not our concern.
The observation is now the specification: contract_activitypods-providers,
stamped at the commit it was read from. A record's id is the resource URI and it
is the only identifier, so the seam's two collapse into one. update fetches,
merges and PUTs, so a partial write is safe and the seam declares this backend
as patching.
What the reading also surfaced matters more than either question. Every
container resolution runs against the session's own WebID — in getList, in
create, in a list subscription alike. So this backend can only ever show a user
their own records: no other user's event is reachable, and an event's
participant count cannot be computed from participations the app cannot read.
That is the product, not a detail, so it is need 1 rather than a friction, and
it is phrased as what it is: the capability sits one layer down, exposed as a
WebID parameter, just not reachable through the data provider.
Four frictions are recorded with the workarounds, including the auth provider's
timer and listener that construction installs and nothing removes — which the
runtime backend switch would accumulate, so the interval goes off and the app
checks status itself.
The Refine seam asks four things of a backend, and the ActivityPods README
answers two: how its providers are configured, and that a declared shape tree
gets its own Data Registration and container on the Pod. It is silent on the
record shape and on whether update replaces or patches — the two the seam
cannot default, and the two that fail silently when wrong.
So the declaration is written before adoption instead of after: the surface is
marked as declared rather than measured, the domain conditions are stated at
full strength, and the two unknowns sit in Needs as requests addressed to the
provider. Reading their source to settle them is the one thing this project
does not do.
This branch had no contract manifest at all, so it gets one. It carries no
consume entry, because neither targeted backend publishes an engagement to
pull; the declaration anchors on the README's commit identity, resolved with
ls-remote, which names a state without fetching any content.
Stopgap staging multi-user sur wallet partagé (cf. brief_2026-06-15_shared-wallet-shim).
Distribution / import du wallet :
- AccessGateScreen : barrière d'accès ON PAR DÉFAUT (désactivable via
globalThis.__FESTIPOD_ACCESS_GATE_DISABLED__ pour tests/dev). Fournit le FICHIER
.ngw + le mot de passe + un guide en 3 étapes (import assisté sur nextgraph.eu —
le broker hébergé n'autorise pas l'import inline pendant l'auth web-app).
- sharedWallet.ts + build.ts : fichier copié en /shared-wallet.ngw, mot de passe gravé.
- Ancien LoginScreen (/login) retiré ; atterrissage post-login -> /home.
- NextGraphContext : dé-piégeage de l'état "connecting" au retour (pageshow/bfcache).
Couche multistore stopgap : storeRegistry, isolation, AccountContext, FestipodDataContext.
Tests e2e multi-navigateur :
- browserPool + world.openBrowser : contextes frais isolés, 2 axes orthogonaux
(nb de navigateurs × modèle de wallet own/shared).
- @humain : parcours humain complet (télécharge -> importe le fichier sur
nextgraph.eu -> Entrer -> pseudo -> accueil).
- Bypass de la barrière pour @e2e via context.addInitScript.
- Convention @wip exclue via cucumber.json.
Docs (concepts) : nextgraph-platform (knowledge_broker-import-constraint,
decision_2026-06-17_assisted-wallet-import), bdd-testing (knowledge_multibrowser-harness).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Couche compte/login + isolation livrées et vérifiées ; couche multi-document
(storeRegistry) livrée derrière FESTIPOD_MULTISTORE/FESTIPOD_STAGING (OFF par
défaut, mono-store reste le défaut), runtime NG à valider sur broker.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Capture the multi-user design exploration as project knowledge + briefs:
- knowledge: NextGraph store types/permissions (+ inbox at protocol, SDK
exposure, local repo path); integration model (iframe, where the verifier
runs, generic JS plumbing, ngd stateful, build-time broker target)
- briefs: multi-store refactor; authorization matrix + query inventory +
derived store partitions; temporary fork to expose the inbox (3 layers:
SDK fork, Coolify self-hosting, Festipod integration; libs via build:ng)
- fix stale @ng-org versions (alpha.11 -> alpha.13) and a broken
decision-record link in data-layer.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The @ng-org/* SDK alpha versions are now published on npm. Switch the
package.json dependencies from .ng-tarballs/*.tgz paths to npm
versions, removing the need for a sibling nextgraph-rs build to
install the project. Makes containerized deploys (Coolify) trivial.
- @ng-org/alien-deepsignals: 0.1.2-alpha.11 (unchanged)
- @ng-org/orm: 0.1.2-alpha.15 → 0.1.2-alpha.18
- @ng-org/shex-orm: 0.1.2-alpha.7 → 0.1.2-alpha.8
- @ng-org/web: 0.1.2-alpha.11 → 0.1.2-alpha.13
scripts/build-ng-packages.sh and the .ng-tarballs/ workflow remain
available for local development against an unreleased nextgraph-rs
build (`.gitignore` keeps the directory ignored).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Port modern clean theme (DM Sans, orange accent, app-* CSS classes)
and screen redesigns from festipod-mockups; replace sketchy Ubuntu
theme. New shared components: BottomNav, EventCover, EventMeetingPoints,
Toast, AvatarStack, Tag, RelevanceIcon.
- Restructure from prototyping shell to real mobile web app:
path-based routing (History API), Gallery/DemoMode/PhoneFrame removed,
Storybook setup for screen/component browsing.
- ConnectScreen ported from mockup (QR-based user connection); routed
at /profile/connect, wired from FriendsListScreen.
- Dev-only auto-seed of NG wallet when empty
(gated on NODE_ENV !== 'production'); bootstrapWallet already
self-checks for non-empty ngSet so safe even in race conditions.
- Render-based @ui test infrastructure: happy-dom + LocalDataProvider +
RouterProvider via src/shared/test-harness/renderHelper.tsx, exposed
on the world as renderedDoc. world.hasText/hasField/hasElement prefer
the rendered DOM and fall back to source for backward compatibility.
- Migrate 25 brittle @ui assertions from regex-on-source to DOM
queries; delete implementation-detail tests (showDuplicateWarning,
importableEvents, importedFrom — anti-patterns per the new contract).
Update feature files where the UI changed: "Mes amis" → "Mon réseau",
"Mes événements à venir" → "À venir" on home, Thématique removed
from create-event wizard, etc.
- Path-based @e2e steps (pushState + popstate dispatch) replacing the
legacy "#/demo/…" hash routing tied to the deleted Gallery.
- Add .project/knowledge/test-layer-contracts.md defining the role of
each test layer (@ui = display with seed data + DOM, @data = mutations
through NG broker, @e2e = critical user journeys) with anti-patterns
and migration consequences.
Test status: 75 passed / 71 skipped (explicit "non implémenté")
/ 2 failed (pre-existing @wip on ngSet.delete() NG ORM limitation).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ngSet.delete() updates the local reactive set but does not persist to the
broker. Use ng.sparql_update() with SPARQL DELETE WHERE to remove RDF triples
directly — the broker sends back a GraphOrmUpdate that reactively removes the
item from the ORM set. The two methods must not be combined as they conflict
in the CRDT.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Writes (doc_create, orm_frontend_update) failed with RepoNotFound because
useShape with did:ng:i scope doesn't open individual repos in the verifier's
cache. Switched to did🆖${session.private_store_id} as both scope and
@graph, matching the expense-tracker-rdf pattern. This opens the private
store repo via orm_start_graph, making it available for subsequent writes.
Also adds wallet login step to ensureAuth so the verifier bootstraps repos
from the remote broker into localStorage on first run.
Key changes:
- useShapeWithDefaults accepts storeNuri param (private store NURI)
- FestipodDataContext.useNgData() passes private store scope
- ensureGraphNuri() simplified: reuse existing @graph or private_store_id
- ngBootstrap uses ensureGraphNuri + flushAndWait between ORM adds
- harness-ng.tsx uses private store scope for test bridge shapes
- hooks.ts: wallet creation logs in to bootstrap verifier repos
- E2e steps for data loading and persistence verification
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add @e2e test layer: real app in broker iframe via Playwright
- Fix broker redirect: conditional auto-init only when inside iframe
- Fix seed data flash: empty data during 'connecting' phase
- Fix Gallery button in iframe: explicit navigate instead of history.back
- Add auth e2e feature scenarios and step definitions
- Update docs: bdd-testing, data-layer-testing, data-layer, AGENTS.md
- Add decision record for conditional NG init approach
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Rename steps/frontend/ to steps/ui/ across all modules and shared
- Add data-layer test harness (mock + real broker modes) with Playwright
- Add inscription data-layer steps (@data scenarios)
- Add test auth setup script and browser debug script
- Update docs (architecture, BDD testing, data-layer testing)
- Add ADR for headless wallet creation decision
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add NextGraph data layer with @ng-org/orm, SHEX shapes (Event, UserProfile,
Participation), session management, and FestipodDataContext with dual-mode
operation (connected via NextGraph or local seed data)
- Add BrokerBanner and NgStatus components showing connection status
- Refactor to feature-based architecture: organize code by business domain
(event, user, home, auth, workshop, meeting, notification) instead of
technical layer. Modules only import from shared/, never from each other
- Collocate BDD features and step definitions with their modules: event-specific
steps in event/steps/, user steps in user/steps/, shared generic steps remain
in shared/steps/
- Set up multi-layer BDD structure (frontend/backend/e2e steps per module)
- Add project documentation (AGENTS.md, .project/knowledge/)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>