Retire a caveat the fix made false, and turn a stale warning into a technique
Four of the five fields the caveat said were silently lost are now persisted, so the caveat is retired rather than trimmed. What was genuinely unique in it -- the inbox predicate being a vestige that must stay unused -- moved into the Event bullet where the shape is described; what merely duplicated the entity leaf went. Only `themes` remains unpersisted, and since nothing reads it back it is a note rather than a hazard. The regeneration warning is reframed rather than deleted. It said the ORM generator had drifted from the committed bindings; that no longer reproduces -- regenerating from the unchanged shape gives byte-identical output. What survives is the technique that established it: run the generator on unchanged input first, so an ORM diff separates cleanly into the author's change and the generator's own. A warning became a way of working. The same stale claim sat independently in the commands leaf and was found by grep, not by the briefing. Recorded where the screen hazards live: the edit form seeds its inputs on first render, so mounted before its event lands in the reactive set it stays blank -- the same class as a value that is empty until a read arrives. Verified rather than assumed: the misleading French date example flagged for correction exists nowhere in the doctrine. It lives in a shape comment and the binding generated from it, both outside this pass, and is noted as such.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
type: knowledge
|
||||
summary: The product model of confidentiality and discovery — every entity lives in the SCOPE matching who must read it (events & meeting points public, network profile & participations protected, settings private, bilateral connections dialog); discovery is reading the public scope
|
||||
summary: The product model of confidentiality and discovery — every entity lives in the SCOPE matching who must read it; other users' events are found through a shared index, not by reading the public scope
|
||||
---
|
||||
|
||||
# Data scopes and discovery
|
||||
@@ -31,7 +31,11 @@ Festipod **places each entity in its scope**; isolation between scopes is **hand
|
||||
|
||||
## Event discovery
|
||||
|
||||
A user discovers the events they did not create simply by **reading the `public` scope**: the app names the shape and the scope, and gets back everyone's public events, not just its own. That is the **primary** discovery axis; a **secondary**, relational one is layered on top (the connections' *protected* participations: "my friends are attending…").
|
||||
Reading the `public` scope only ever returns **this session's own** public documents — there is no call that unions every user's public store (concept `data-layer`, [[contract_polyfill-surface]]). A declared event was therefore reachable by its declarer alone, which made the whole cross-user sign-up flow — the product's premise — unreachable.
|
||||
|
||||
**A user discovers events they did not create through a shared index**: an ordinary public document, indistinguishable from any other, that the app reaches by a reference it hardcodes. Anyone may deposit a reference to their event into it; only the index's owner curates those deposits into visible entries, ordered by the event's start date. This is the **primary** discovery axis, settled as [[decision_2026-08-17_discovery-through-a-shared-index]] (concept `data-layer`) — **no code consumes the index yet.** A **secondary**, relational axis stays layered on top: the connections' *protected* participations ("my friends are attending…").
|
||||
|
||||
Four costs come with it, accepted rather than solved: an event becomes findable only once **someone curates** the index, on no fixed schedule — curation is an operator role, not a feature that runs itself; an event declared before its document could carry the field the index reads never becomes findable through it, permanently; a withdrawn or later-corrected event **stays listed** — nothing here removes an entry, so a reader of the index must tolerate a reference that no longer resolves, or resolves to something changed; and an event's position in the list is **frozen at the moment it was curated** — correcting its date afterwards does not move it. Full mechanics and the rejected alternative: [[decision_2026-08-17_discovery-through-a-shared-index]].
|
||||
|
||||
> **Sign-up notification (product intent).** Signing up to a meeting point notifies its host: identified if the participant is one of the host's connections, **unnamed otherwise**. This "identified if known, unnamed otherwise" falls out of scope placement — the host can read the sign-up, but not the *protected* profile it points at unless they are connected. The app states the intent; it implements no filter of its own.
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ summary: What is implemented today (event + meeting point lifecycle, profiles, c
|
||||
- User profile, profile update, profile sharing
|
||||
- Friends list (connections), another user's profile
|
||||
|
||||
> **Signing up is wired step by step, and the count a bystander sees lags the flow by one connection.** Each step is honest: `joinEvent` persists a Participation and deposits into the event's inbox, where its owner reads it; `leaveEvent` deletes the Participation authoritatively (concept `data-layer`, [[caveat_participation-deletion]]); neither succeeds in silence, and the confirmation the user sees follows the write. Driven end to end in a real browser, the signer's own confirmation is instant and correct, but the `participantCount` a bystander sees stays at 0 through the session and the first reconnect, only catching up on the second — a known layer limitation, not data loss (concept `data-layer`, [[caveat_participant-count-one-connection-lag]]). Nothing short of exercising the whole thing end to end shows this kind of gap (concept `bdd-testing`, [[cookbook_live-probe]]). Treat the bullet above as *screens reachable*, not as an instantly-consistent journey. Public discovery — a user seeing another user's public event — works too.
|
||||
> **Signing up is wired step by step, and the count a bystander sees lags the flow by one connection.** Each step is honest: `joinEvent` persists a Participation and deposits into the event's inbox, where its owner reads it; `leaveEvent` deletes the Participation authoritatively (concept `data-layer`, [[caveat_participation-deletion]]); neither succeeds in silence, and the confirmation the user sees follows the write. Driven end to end in a real browser, the signer's own confirmation is instant and correct, but the `participantCount` a bystander sees stays at 0 through the session and the first reconnect, only catching up on the second — a known layer limitation, not data loss (concept `data-layer`, [[caveat_participant-count-one-connection-lag]]). Nothing short of exercising the whole thing end to end shows this kind of gap (concept `bdd-testing`, [[cookbook_live-probe]]). Treat the bullet above as *screens reachable*, not as an instantly-consistent journey. **Public discovery does not work yet**: a user sees another user's public event only once a shared index exists and is curated (concept `data-layer`, [[decision_2026-08-17_discovery-through-a-shared-index]]; concept `functional-domain`, [[knowledge_data-scopes-and-discovery]]) — no code consumes it today.
|
||||
|
||||
> **Updating an event is reserved to its declarer**, and the interface says so rather than discovering it late: the edit route is decided by ownership, and the confirmation follows the write instead of preceding it (concept `app-architecture`, [[knowledge_screen-pattern]]). Owner-only is not a policy choice here — it is the only reading the data model allows ([[knowledge_data-scopes-and-discovery]]).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user