Skip to content

push: bounded NIP-9a callbacks and opt-in lettered capability advertisements - #23

Merged
FelineStateMachine merged 1 commit into
mainfrom
feat/nip-9a-push
Sep 4, 2026
Merged

push: bounded NIP-9a callbacks and opt-in lettered capability advertisements#23
FelineStateMachine merged 1 commit into
mainfrom
feat/nip-9a-push

Conversation

@FelineStateMachine

Copy link
Copy Markdown
Owner

Motivation

Community/inbox notifications and Git or automation hooks currently need an external listener to remain connected. Opt-in NIP-9a registrations let the relay deliver matching events to an approved callback after publication. This is relay-to-callback delivery; applications still supply their own mobile push infrastructure.

This PR is stacked on #22 (feat/nip-ad-web-addresses). Merge #22 first, then retarget this PR to main. The shared capability registry advertises AD only with that implementation present. NIP-86 claims (#21) is independent.

Change

  • Pin NIP-9a proposal #2194 to 5a908b8dc5190a46eac47992cba5ba6d8e7fc094. Authenticated owners/members publish private kind 30390 registrations with relay, filter/ignore, callback and optional include_event tags.
  • Default push off. A host-owned exact HTTPS origin allowlist intersects relay-owner callback policy. No redirects, arbitrary tenant egress, IP literals, credentials or nonstandard ports. Operators must trust approved callback DNS ownership and public routing.
  • Persist bounded delivery references and terminal outcomes. Recheck current membership, read/write policy, event visibility and callback approvals before each attempt. Deletion/replacement, member removal and policy changes cancel queued work; 404 removes registrations. Slow callbacks run outside repository admission, so they cannot stall unrelated event publication.
  • Bound registrations to 32 per relay/4 per author, queue to 256 with 24-hour expiry, rounds to 4 requests with 5-second timeouts, and retries to 4 attempts. Work and storage use fuel accounting. Best-effort delivery may lose notifications or duplicate an ambiguous request; receivers deduplicate.
  • Make registrations author-only across REQ/COUNT/sync/HTTP/live delivery and exclude them from shared exports, dashboards and rebroadcast jobs, even with push disabled.
  • Preserve numeric NIP-11 output by default. letteredNips opts into mixed identifiers; push requires mixed output. The common registry covers 5A when sites are enabled, 9a when push is enabled, and implemented AD. Numeric capabilities remain numbers. Config/schema, console and docs include the policy.

Compatibility research pins PR #2218 to b4bad62ad44a900d6800e83c1f83549f2f705c33. Amethyst explicitly accepts mixed arrays; installed nostr-tools accepts raw JSON and keeps numeric lookups working with mixed entries. Damus metadata and the inspected Rust integer decoder reject lettered values. This is not a universal compatibility claim or proof of a Damus WebSocket failure. Disable push and letteredNips for numeric-only metadata. Concrete sources and uncertainties are in docs/26-nip11-compatibility.md.

Testing Completed

  • npm run typecheck: TypeScript, generated signer/console/templates, console startup, host config parity, and all relay template schemas pass.
  • npm test -- --maxWorkers=4: 48 files, 246 tests pass on the AD baseline.
  • Controlled callback tests cover full/ID-only payloads, filtering, admission, private-event authorization, queue bounds, member removal/re-addition, disabled/re-enabled policy, hidden events, retries/network failure/timeout, crash attempt exhaustion, 404 cleanup, slow-callback concurrency, late alarm scheduling and teardown recovery. No callback POSTs went to uncontrolled public services.
  • Author-only privacy tests exercise HTTP query/count, authenticated WebSocket reads/live delivery, Store queries/HLL/sync and export/job/dashboard paths.
  • Ran the installed nostr-tools fetch helper with numeric, mixed and all-string response fixtures; reproduced the Damus integer decoder shape with Swift JSONDecoder. Full external client applications and mobile push services were not run.
  • Independent subagent privacy/security review; findings and integration test issues resolved. No merge or deployment.

Responsible AI disclosure

Implemented with Codex and subagents for research, implementation, tests and review. Codex checked source evidence, corrected research inaccuracies, and ran the project checks; human review is requested for the draft-protocol and callback trust decisions.

Base automatically changed from feat/nip-ad-web-addresses to main September 4, 2026 23:52
… lettered capability advertisements

Registrations require member authentication and host-approved HTTPS origins. Delivery persists finite retries, rechecks current access, meters work and isolates callback latency from publication. Numeric NIP identifiers remain unchanged; lettered advertisements document client compatibility limits.
@FelineStateMachine
FelineStateMachine merged commit 7dc805d into main Sep 4, 2026
1 check passed
@FelineStateMachine
FelineStateMachine deleted the feat/nip-9a-push branch September 4, 2026 23:55
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