Files
amethyst/.claude
Claude de34f392a9 fix(quartz): a superseded replaceable is REPLACED (OK false), not a duplicate
A replaceable/addressable version that a stored one already beats is not
written. Since 18c576a068 the SQLite store has reported it as SUPERSEDED,
"duplicate: a newer version ...", and RelaySession acks every `duplicate:`
reason with OK true. So a client was told its event is on the relay when
no REQ will ever return it. NIP-01's third OK field is `true` when the
event was accepted.

classifyRowError now answers RejectionReason.REPLACED,
`replaced: a newer version exists`, which RelaySession sends as OK false.
That is strfry's answer too (`false, "replaced: have newer event"`). It
also names the case correctly: the relay does not have THIS event, it has
a newer one.

The W09 work is untouched. Classification still asks the database rather
than the driver's message, so Android's null-message constraint failures
still classify correctly, and a byte-for-byte re-offer of a stored version
is still DUPLICATE (OK true).

The MDK `wn` loop 18c576a068 was fixing (a second KeyPackage minted in the
same second) now gets `OK false replaced:` instead of raw constraint text,
which was the unclassifiable part. Retrying a `replaced:` rejection cannot
succeed, so that is for the client to stop doing, not for the relay to
paper over with OK true.

RejectionReason.SUPERSEDED stays, @Deprecated in favour of REPLACED, for
source compatibility. NostrServerTest and InsertOutcomeClassificationTest
flip their expectations, and the event-store-semantics skill updates
W01/W02 and W09 and adds a changelog entry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AdSGU88PYrRVyVHjiEc5sw
2026-09-27 14:33:13 +00:00
..