> This is a backwards-compatible protocol change (it introduces a new data format and semantics). Also, I would recommend using a specific event kind, rather than overloading an existing one with new semantics.
I think we still differ on what counts as a protocol change.
A NIP-01 event with extra tags is not a protocol change. Clients already ignore tags they don’t care about. Relays already store opaque JSON.
Nothing here requires new relay behavior, new permissions, or any protocol level understanding of lineage. That’s all I mean by “no protocol change.”
If a client wants to support rotation, it only needs to:
- discover a lineage event for the pubkey it’s currently using
- verify sig_root(epoch_pubkey)
- switch its notion of “current key” to the new one
That’s it. No republishing. No rewriting old events. No sibling traversal. No multi directional crawling. Events stay exactly where they were signed. This is not a delegation graph and not a multi hop merge. It’s a single step ancestry link.
Given a key A, the client only needs to ask:
“Is there a valid lineage event pointing to A’ that supersedes it?”
If yes → follow A’.
If no → stay on A.
Old posts stay with old keys. New posts come from new keys. There is no expectation that a new epoch key republishes content from prior epochs. If a client doesn’t implement this, nothing breaks. If it does, identity becomes survivable.
> I'm not sure I completely understand how the link works and what clients are expected to do with it. Say I pull a kind 0 signed by key A' with a link to A. Does A' re-publish a kind 0 (for example), or are clients expected to map the key and fetch A's kind 0? Or vice versa? Or, given a key A'', how do you fetch events published by sibling keys? Or are clients only expected to migrate follows etc when a new epoch happens?
Epoch rotation is not about remapping past events or merging siblings. Clients don’t need to crawl anything or reconcile historical state.
The model is intentionally simple:
- old events stay under the key that signed them
- new events come from the new epoch key
- the lineage event tells the client which key to treat as “current”
Nothing is republished. Nothing is rewritten. Nothing is fetched from siblings. A client doesn’t need to fetch events from A1, A2, A3 or merge timelines. It only needs to know which key is the active identity for new actions.
If a client sees a valid lineage event saying A → A’, it just switches its posting identity and UI identity to A’.
Historical fetch stays unchanged:
- events(pubkey=A) returns old posts
- events(pubkey=A') returns new posts
This mirrors Bitcoin wallet key rotation and PGP subkey rotation. Identity moves forward, history stays with the key that signed it. No republishing. No follow migration by clients. No multi key merge logic.
The only responsibility of the client is:
- detect the lineage event
- verify the root signature
- follow the newer key going forward
Everything else is intentionally untouched.