TemplateResourceForm: create mode is unguarded against a same-second collision at a user-chosen address #74
Labels
No labels
bug
discussion
enhancement
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
edufeed/edufeed-app#74
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Follow-up from #72 / PR #73, measured by TestOER while verifying that fix. Not a regression from #73 — it is the boundary the #73 guard deliberately does not cover.
What happens
TemplateResourceForm.svelteguards edit mode only:In create mode there is no predecessor in hand, so the timestamp is just "now". That is fine when the address is new — but the address is not guaranteed to be new.
resolveResourceDTag(src/lib/helpers/educational/formReference.js:35-43) takes the create-modedtag fromemittedD, i.e. the form'samb:idfield — a url the user types. So the same author can create at an address that already holds a resource, with no edit involved.Measured as shipped (TestOER, local relay,
10cdb4f8)The client caches and renders its own version while the relay still serves the old one, and a cache hit ends the address loader before any relay is asked — so the divergence is not self-healing on reload.
Scope, stated honestly
created_attie, so on a conforming relay this diverges roughly half the time, not always.Narrow. But it is #62's class of bug (client and relay disagree about which version is current, silently), at the one boundary #73 left open.
Why it was left open, and what a fix would cost
The edit-mode guard works because the predecessor event is already loaded. Create mode has nothing to compare against, so a real fix means looking the address up before publishing — an
eventStore.replaceable(30142, pubkey, dTag)check plus, for correctness against a relay we have never queried, anaddressLoaderround trip. That turns a synchronous submit into an async pre-flight and adds a "this url already has a resource — edit it instead?" decision that is arguably a UX question, not a timestamp question.Options
eventStorealready holds an event at(pubkey, dTag)in create mode, pass it tonextCreatedAt— same one-line shape as edit mode. Closes the case where the resource was loaded this session; silent no-op otherwise.addressLoader+ surface "this address is taken" in the form.Recommendation: 2, if anything. It is the same guard already in the file, costs nothing, and cannot make the current behaviour worse. 3 is a UX decision for @laoc_buzz.
Evidence and setup:
RESEARCH/ISSUE_72_TEMPLATE_RESOURCE_FORM_GUARDS.md(TestOER).