Toggling all-day on an existing calendar event changes the kind, so nothing is replaced (split from #62) #65

Closed
opened 2026-07-30 13:21:45 +00:00 by laoc · 0 comments
Owner

Split out of #62, which is now closed. The stale-read half of #62 is fixed and verified (20/0 at 961c3a82); this half is not fixed and needs a product decision, so it gets its own issue rather than being buried in a closed one.

The bug

updateEvent() builds the replacement with:

kind: eventData.kind || existingEvent.kind

src/lib/stores/calendar-actions.svelte.js

and convertFormDataToEvent() sets the kind from the form's all-day state:

src/lib/helpers/calendar.js:347   event.kind = 31922;   // date-based
src/lib/helpers/calendar.js:357   event.kind = 31923;   // time-based

So toggling all-day on an existing event changes the kind while keeping the d-tag.

Under NIP-01 a parameterized replaceable event is addressed by (kind, pubkey, d-tag). A different kind is a different coordinate, so the original is never replaced:

  • two live events at two coordinates, both valid, neither superseding the other
  • the naddr already in the URL encodes the old kind, so it keeps resolving to the stale one
  • the create path is unaffected — this only bites on edit

Still not reproduced in a browser. It is a code read, re-verified on dev at b82bfe9c after the #62 merge. It was explicitly not the cause of the three #62 e2e failures — none of them touch the toggle.

Why it needs a product call, not just a fix

There is no way to move an event between 31922 and 31923 that is both correct and lossless, so someone has to choose:

  1. Delete-and-recreate — publish a NIP-09 kind 5 for the old coordinate, then create at the new one. Correct on the relay, but the naddr changes, so existing links, RSVPs (kind 31925 reference the old a) and shares (kind 30222) break. Deletion is also not guaranteed to propagate to every relay.
  2. Block the toggle on edit — grey it out with an explanation, keep the coordinate stable. Lossless and honest, but a user who picked the wrong mode at creation has to delete and start over.
  3. Allow the fork knowingly — current behaviour, plus a warning. I would not pick this; two live events at two coordinates with no relationship between them is the worst outcome for anything downstream.

My recommendation is (2) for now: it is the only option that cannot corrupt existing references, and it is a small, testable change. (1) is defensible later if the RSVP/share fallout is handled deliberately.

@laoc_buzz — this one is yours to call.

  • #62 — the stale-read bug this was filed alongside (fixed, closed)
  • #64 — the sibling eventStore.add omissions, and the created_at tie applying to every replaceable update
Split out of #62, which is now closed. The stale-read half of #62 is fixed and verified (20/0 at `961c3a82`); **this half is not fixed and needs a product decision**, so it gets its own issue rather than being buried in a closed one. ## The bug `updateEvent()` builds the replacement with: ```js kind: eventData.kind || existingEvent.kind ``` `src/lib/stores/calendar-actions.svelte.js` and `convertFormDataToEvent()` sets the kind from the form's all-day state: ``` src/lib/helpers/calendar.js:347 event.kind = 31922; // date-based src/lib/helpers/calendar.js:357 event.kind = 31923; // time-based ``` So **toggling all-day on an existing event changes the kind while keeping the d-tag.** Under NIP-01 a parameterized replaceable event is addressed by `(kind, pubkey, d-tag)`. A different kind is a **different coordinate**, so the original is never replaced: - two live events at two coordinates, both valid, neither superseding the other - the naddr already in the URL encodes the *old* kind, so it keeps resolving to the stale one - the create path is unaffected — this only bites on edit Still **not reproduced in a browser.** It is a code read, re-verified on `dev` at `b82bfe9c` after the #62 merge. It was explicitly *not* the cause of the three #62 e2e failures — none of them touch the toggle. ## Why it needs a product call, not just a fix There is no way to move an event between 31922 and 31923 that is both correct and lossless, so someone has to choose: 1. **Delete-and-recreate** — publish a NIP-09 kind 5 for the old coordinate, then create at the new one. Correct on the relay, but the naddr changes, so existing links, RSVPs (kind 31925 reference the old `a`) and shares (kind 30222) break. Deletion is also not guaranteed to propagate to every relay. 2. **Block the toggle on edit** — grey it out with an explanation, keep the coordinate stable. Lossless and honest, but a user who picked the wrong mode at creation has to delete and start over. 3. **Allow the fork knowingly** — current behaviour, plus a warning. I would not pick this; two live events at two coordinates with no relationship between them is the worst outcome for anything downstream. My recommendation is **(2) for now**: it is the only option that cannot corrupt existing references, and it is a small, testable change. (1) is defensible later if the RSVP/share fallout is handled deliberately. @laoc_buzz — this one is yours to call. ## Related - #62 — the stale-read bug this was filed alongside (fixed, closed) - #64 — the sibling `eventStore.add` omissions, and the `created_at` tie applying to every replaceable update
laoc closed this issue 2026-07-30 14:09:13 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
edufeed/edufeed-app#65
No description provided.