Since you mentioned encrypted document workflows, you likely suspected that we can't rely on the server to manage state transitions. You are correct: we rely entirely on client-side validation of "Replaceable Events" (Nostr NIP-01/NIP-33).
Here is the pattern OpenSlots uses to handle availability changes:
The Mechanism: Parameterized Replaceable Events
The original text mentioned "publishing encrypted, replaceable events." In the Nostr protocol, this refers to specific event kinds where relays are instructed to only store the newest version of an event from a specific pubkey with a specific identifier (the d tag).
1. Immutable Identity, Mutable State: The "Room" or "Schedule" is identified by a deterministic ID (derived from the random seed in the URL). This is the d tag.
2. The Update Loop:
- When the host changes availability (e.g., removes a Tuesday slot), the client generates a new availability bitmask.
- It encrypts this new payload with the same key (so existing URL holders can still read it).
- It signs and publishes a new event with the same d tag but a newer created_at timestamp.
3. Resolution (LWW):
- Relay Side: Relays discard the old event and store the new one (purely based on timestamp and ID, zero knowledge of content).
- Client Side: Even if a relay sends multiple versions (due to propagation delay), the client logic applies a Last-Write-Wins (LWW) policy, simply rendering the event with the latest timestamp.
Why this works for Scheduling
Since scheduling (in this specific context) is usually single-writer (the host defines availability) and multi-reader (attendees view it), we avoid complex merge conflicts.
- Host: Sole authority on the "Availability" event.
- Attendees: Sole authority on their own "Request/Booking" events.
If an attendee tries to book a slot that was just removed (a "stale read"), the host's client—upon receiving the booking request—checks it against its current local state and rejects it cryptographically (or simply ignores it), preventing the double-booking.
Here is the pattern OpenSlots uses to handle availability changes:
The Mechanism: Parameterized Replaceable Events
The original text mentioned "publishing encrypted, replaceable events." In the Nostr protocol, this refers to specific event kinds where relays are instructed to only store the newest version of an event from a specific pubkey with a specific identifier (the d tag).
1. Immutable Identity, Mutable State: The "Room" or "Schedule" is identified by a deterministic ID (derived from the random seed in the URL). This is the d tag.
2. The Update Loop: - When the host changes availability (e.g., removes a Tuesday slot), the client generates a new availability bitmask. - It encrypts this new payload with the same key (so existing URL holders can still read it). - It signs and publishes a new event with the same d tag but a newer created_at timestamp.
3. Resolution (LWW): - Relay Side: Relays discard the old event and store the new one (purely based on timestamp and ID, zero knowledge of content). - Client Side: Even if a relay sends multiple versions (due to propagation delay), the client logic applies a Last-Write-Wins (LWW) policy, simply rendering the event with the latest timestamp.
Why this works for Scheduling
Since scheduling (in this specific context) is usually single-writer (the host defines availability) and multi-reader (attendees view it), we avoid complex merge conflicts.
- Host: Sole authority on the "Availability" event. - Attendees: Sole authority on their own "Request/Booking" events.
If an attendee tries to book a slot that was just removed (a "stale read"), the host's client—upon receiving the booking request—checks it against its current local state and rejects it cryptographically (or simply ignores it), preventing the double-booking.
reply