Skip to content

docs: add NIP-ER event reminders#875

Merged
tlongwell-block merged 6 commits into
mainfrom
max/nip-er-docs
Jun 9, 2026
Merged

docs: add NIP-ER event reminders#875
tlongwell-block merged 6 commits into
mainfrom
max/nip-er-docs

Conversation

@tlongwell-block

@tlongwell-block tlongwell-block commented Jun 5, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add docs/nips/NIP-ER.md for encrypted event reminders
  • define kind:30300 reminder state with public not_before due-time signals
  • document relay/client behavior, privacy limits, NIP-42-gated reads, and NIP-09 deletion
  • add NIP-corpus scaffolding: motivation, non-goals, terminology, relationship to other NIPs, security considerations, and worked examples

Sprout note

Sprout has a historical unused kind:40007 / KIND_STREAM_REMINDER reservation. That is not part of NIP-ER. NIP-ER is intended to be implementable by any Nostr project and uses kind:30300 with not_before.

Verification

  • git diff --check
  • doc sanity script confirmed the structural sections are present, no Sprout-specific legacy/protocol text remains in the NIP body, no NIP-XX placeholders remain, generic draft discovery is present, and the since/privacy/range clarifications are present
  • pre-commit hook passed during amend

Notes

Local pre-push hook was bypassed with --no-verify because an unrelated existing Rust/Tauri check fails on sprout-desktop using unstable str::floor_char_boundary in src/commands/agent_discovery.rs. This PR is docs-only.

@tlongwell-block tlongwell-block requested a review from a team as a code owner June 5, 2026 16:12
@tlongwell-block tlongwell-block force-pushed the max/nip-er-docs branch 6 times, most recently from e13de6f to 0bdf275 Compare June 5, 2026 19:56
Signed-off-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d added 4 commits June 9, 2026 09:40
…rt-dedupe caveat

- intro/Non-Goals: delivery is relay-dependent; push-mode relays MUST emit due signals
- Client behavior: add stateless notification profile (non-deduping receive path,
  discard if not_before > W in future without recording, hold and fire within W,
  RECOMMENDED W=60s, one-shot queries for management)
- scope the dedupe MUST to persisted reminder state (transport vs state layer)

Wording agreed in reminder-messages thread (Eva/Max/Tyler).

Signed-off-by: npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@sprout-oss.stage.blox.sqprod.co>
Exhaustive state-machine exploration (83k configs: push/lazy relay x
raw/pool-deduped path x clock skew x W x action schedules) found three
gaps in the profile as worded; each sentence added here closes one:

- 'every delivery supersedes any held event for the same address':
  without it, a held reminder fires even after a delivered snooze
  replacement (stale notify, 157 counterexamples)
- 'SHOULD NOT notify the same event id again': without it, reconnect
  replay or repeated due signals after firing re-notify (double-notify)
- 'W SHOULD exceed worst-case client clock skew': a client behind by
  more than W discards the due-time redelivery itself as too far in
  the future and the reminder is lost until reconnect

With these, the modeled client satisfies: due pending heads always
notify (push relay, conforming path), never early, never terminal,
at most once per id; residual staleness only in offline multi-device
races the spec already documents.

Signed-off-by: npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@sprout-oss.stage.blox.sqprod.co>
'will not fire on relays that do not implement this NIP' was too strong:
on a lazy or non-supporting relay the profile still fires for reminders
already within W of due when the stored head is replayed at query time
(model-checked both directions). State the actual behavior and tie the
full guarantee to push-mode advertisement.

Signed-off-by: npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@sprout-oss.stage.blox.sqprod.co>
…veat

Three model-verified gaps from review:
- push-mode relays SHOULD replay the latest due reminder on subscriptions
  opened after not_before (pins reconnect liveness to NIP-01 stored replay)
- the notification path must parse the reminder address before discarding,
  or address-supersede cannot work (discard-without-recording tension)
- NIP-09 kind:5 deletions do not reach kind:30300 notification paths;
  publish a cancelled replacement first to suppress a held notification

Signed-off-by: npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@sprout-oss.stage.blox.sqprod.co>
…upported

Signed-off-by: npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@sprout-oss.stage.blox.sqprod.co>
@tlongwell-block tlongwell-block merged commit 7b3012b into main Jun 9, 2026
15 checks passed
@tlongwell-block tlongwell-block deleted the max/nip-er-docs branch June 9, 2026 14:02
tlongwell-block pushed a commit that referenced this pull request Jun 9, 2026
* origin/main: (32 commits)
  docs: add NIP-ER event reminders (#875)
  feat(acp): pass slash commands through to ACP connectors (#919)
  fix(sdk): resolve multi-word display names and add NIP-27 nostr:npub mention extraction (#905)
  fix(desktop): re-enable mcp_command reconciliation and harden spawn site (#909)
  Fix desktop DM and sidebar UI polish (#908)
  Animate reaction counts (#904)
  Mobile custom emoji + settings redesign (#906)
  Renew TTL when unarchiving ephemeral channels (#902)
  chore(release): release version 0.3.13 (#903)
  Collapse channel header actions (#901)
  sprout-agent: make Databricks defaults env-only (#868)
  Restyle settings sections (#894)
  Add emoji reaction particles (#890)
  Move settings into the app shell (#893)
  Tune chat text sizing (#891)
  Style channel header navigation (#889)
  fix: rename missed known_acp_provider_exact → known_acp_runtime_exact (#900)
  chore(deps): update radix-ui-primitives monorepo (#898)
  chore(deps): update actions/checkout digest to df4cb1c (#897)
  refactor: rename ACP "provider" to "runtime" across the codebase (#783)
  ...

# Conflicts:
#	desktop/src/features/agents/ui/CreateAgentDialog.tsx
tlongwell-block pushed a commit that referenced this pull request Jun 9, 2026
* origin/main: (32 commits)
  docs: add NIP-ER event reminders (#875)
  feat(acp): pass slash commands through to ACP connectors (#919)
  fix(sdk): resolve multi-word display names and add NIP-27 nostr:npub mention extraction (#905)
  fix(desktop): re-enable mcp_command reconciliation and harden spawn site (#909)
  Fix desktop DM and sidebar UI polish (#908)
  Animate reaction counts (#904)
  Mobile custom emoji + settings redesign (#906)
  Renew TTL when unarchiving ephemeral channels (#902)
  chore(release): release version 0.3.13 (#903)
  Collapse channel header actions (#901)
  sprout-agent: make Databricks defaults env-only (#868)
  Restyle settings sections (#894)
  Add emoji reaction particles (#890)
  Move settings into the app shell (#893)
  Tune chat text sizing (#891)
  Style channel header navigation (#889)
  fix: rename missed known_acp_provider_exact → known_acp_runtime_exact (#900)
  chore(deps): update radix-ui-primitives monorepo (#898)
  chore(deps): update actions/checkout digest to df4cb1c (#897)
  refactor: rename ACP "provider" to "runtime" across the codebase (#783)
  ...

Signed-off-by: npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@sprout-oss.stage.blox.sqprod.co>

# Conflicts:
#	desktop/src/features/agents/ui/CreateAgentDialog.tsx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant