mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-30 07:37:38 +00:00
Adds typed classes for the app-release trust kinds and the kind-30301 collision found in the 2026-10-08 relay census: - 30509 IdentityProofEvent (experimental/zapstore/identityProof): links an APK signing certificate (d = SHA-256 of its DER) to the publishing npub. Exposes the signed message, expiry, revocation, certificateHashMatches() and verifyEd25519Signature(); RSA / P-256 proofs (every live one) need an X.509 parser and verifiers Quartz does not have. - 9401 AssetBundleEvent (experimental/walletScrutiny/assetBundle): release files registered by hash for reproducible-build checks; reuses NIP-82's `i` / `version` tags and joins NIP-82 assets by hash. - 30301 BuildVerificationEvent (experimental/walletScrutiny/verification): the verdict, verified hashes, attachments and the based-on verification; searchable by its description and markdown report. - 30301 KanbanBoardEvent and 30302 KanbanCardEvent (experimental/kanban), per NIP PR #1665, searchable by title and description. Kind 30301 is shared, so EventFactory picks the class by tags as it does for 38000: `i` + `status` is a verification, a title or named column a board, and the encrypted planner app's tasks fall to UnrecognizedKind30301Event. Kind 30302 does the same for Fieldbook's team memberships (UnrecognizedKind30302Event). Probes answer as the board and the card. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FrQx1ZvQka64aFAnZM1Hjd
279 lines
28 KiB
Markdown
279 lines
28 KiB
Markdown
# Searchable kinds — the authoritative implementor table
|
||
|
||
Every concrete `SearchableEvent` implementor in Quartz, with the exact `indexableContent()`
|
||
expression. **Update this file in the same PR as any change to the searchable set or to an
|
||
`indexableContent()` body** (see SKILL.md). Verified against the code 2026-10-08.
|
||
|
||
Counts: 201 concrete classes covering 201 kind values (`GitStatusEvent` spans 4 kinds;
|
||
kind 30063 is shared by two NIPs, kind 38000 by three classes, kind 30301 by two and kind 38385 with other apps — see the footnotes). The kind
|
||
set is exactly `SearchableKinds.ALL` (`nip50Search/SearchableKinds.kt`). File paths are under
|
||
`quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/`.
|
||
|
||
Separator legend: **NL** = `joinToString("\n")`, **SP** = `joinToString(" ")`.
|
||
|
||
| Kind | Class | Package | `indexableContent()` |
|
||
|---|---|---|---|
|
||
| 0 | MetadataEvent | nip01Core/metadata | `contactMetaData()?.let { listOfNotNull(it.name, it.displayName, it.about, it.nip05, it.lud06, it.lud16, it.website, it.picture, it.banner).joinToString(" ") } ?: ""` (SP) |
|
||
| 1 | TextNoteEvent | nip10Notes | `listOfNotNull(subject(), content)` NL |
|
||
| 5 | DeletionRequestEvent | nip09Deletions | `content` (the deletion reason) |
|
||
| 9 | ChatEvent | nipC7Chats | `content` |
|
||
| 11 | ThreadEvent | nip7DThreads | `listOfNotNull(title(), content)` NL |
|
||
| 14 | ChatMessageEvent | nip17Dm/messages | `listOfNotNull(subject(), content)` NL |
|
||
| 15 | ChatMessageEncryptedFileHeaderEvent | nip17Dm/files | `summary().orEmpty()` — `content` is the encrypted file's URL, not text |
|
||
| 20 | PictureEvent | nip68Picture | `(listOfNotNull(title(), content) + location() + imageDescriptions())` NL — `location` tag values, then each imeta's non-blank `alt` |
|
||
| 21 | VideoNormalEvent | nip71Video | inherited `RegularVideoEvent`: `(listOfNotNull(title(), content) + segmentTitles())` NL |
|
||
| 22 | VideoShortEvent | nip71Video | inherited `RegularVideoEvent`: `(listOfNotNull(title(), content) + segmentTitles())` NL |
|
||
| 24 | PublicMessageEvent | nipA4PublicMessages | `content` |
|
||
| 31 | ExternalCitationEvent | experimental/citations | inherited `CitationEvent`: `listOfNotNull(title(), summary(), content, author(), publishedBy())` NL |
|
||
| 32 | HardcopyCitationEvent | experimental/citations | `listOfNotNull(title(), chapterTitle(), summary(), content, author(), editor(), publishedIn(), publishedBy())` NL |
|
||
| 33 | PromptCitationEvent | experimental/citations | `listOfNotNull(title(), summary(), content, author(), publishedBy(), llm())` NL |
|
||
| 40 | ChannelCreateEvent | nip28PublicChat/admin | `channelInfo().let { listOfNotNull(it.name, it.about, it.picture).joinToString(" ") }` (SP) |
|
||
| 41 | ChannelMetadataEvent | nip28PublicChat/admin | same as kind 40 (SP) |
|
||
| 42 | ChannelMessageEvent | nip28PublicChat/message | `content` |
|
||
| 43 | ChannelHideMessageEvent | nip28PublicChat/admin | `reason()` — the `reason` of NIP-28's `{"reason": …}` JSON content, or the plain-text content |
|
||
| 44 | ChannelMuteUserEvent | nip28PublicChat/admin | `reason()` — as kind 43 |
|
||
| 54 | PodcastEpisodeEvent | nipF4Podcasts/episode | `listOfNotNull(title(), description(), content)` NL |
|
||
| 62 | RequestToVanishEvent | nip62RequestToVanish | `content` |
|
||
| 64 | ChessGameEvent | nip64Chess/game | `searchText().all()` NL — the PGN's `Event`, `Site`, `White`, `Black`, `Annotator`, `Opening`, `Variation`, `WhiteTeam`, `BlackTeam` tag-pair values, then its `{…}` comments; never the movetext |
|
||
| 818 | WikiMergeRequestEvent | nip54Wiki | `content` |
|
||
| 1010 | TextNoteModificationEvent | experimental/edits | `listOfNotNull(content, summary())` NL (content first) |
|
||
| 1022 | BidConfirmationEvent | nip15Marketplace/bidConfirmation | `confirmationData()?.message.orEmpty()` — the `message` field of the JSON content |
|
||
| 1063 | FileMetadataEvent | nip94FileMetadata | `listOfNotNull(summary(), content)` NL |
|
||
| 1065 | FileStorageHeaderEvent | experimental/nip95/header | `listOfNotNull(summary(), content)` NL — the caption; the base64 payload lives in the separate 1064 and is never indexed |
|
||
| 1068 | PollEvent | nip88Polls/poll | `buildString { append(content); options().forEach { append('\n').append(it.label) } }` |
|
||
| 1111 | CommentEvent | nip22Comments | `(listOf(content) + tags.hashtags())` NL |
|
||
| 1163 | ProfileGalleryEntryEvent | experimental/profileGallery | `listOfNotNull(summary())` NL |
|
||
| 1301 | WorkoutRecordEvent | experimental/fitness/workout | `listOfNotNull(title(), content)` NL |
|
||
| 1311 | LiveActivitiesChatMessageEvent | nip53LiveActivities/chat | `(listOf(content) + tags.hashtags())` NL |
|
||
| 1312 | LiveActivitiesRaidEvent | nip53LiveActivities/raid | `content` |
|
||
| 1313 | LiveActivitiesClipEvent | nip53LiveActivities/clip | `listOfNotNull(title(), content)` NL |
|
||
| 1315 | RoadEventReportEvent | experimental/roadstr/report | `content` |
|
||
| 1337 | CodeSnippetEvent | nipC0CodeSnippets | `listOfNotNull(snippetName(), snippetDescription(), content)` NL |
|
||
| 1617 | GitPatchEvent | nip34Git/patch | `content` |
|
||
| 1618 | GitPullRequestEvent | nip34Git/pr | `(listOfNotNull(subject(), content) + labels())` NL |
|
||
| 1621 | GitIssueEvent | nip34Git/issue | `(listOfNotNull(subject(), content) + topics())` NL |
|
||
| 1622 | GitReplyEvent | nip34Git/reply | `content` |
|
||
| 1624 | GitCoverNoteEvent | nip34Git/coverNote | `content` (markdown cover note) |
|
||
| 1630–1633 | GitStatusEvent | nip34Git/status | inherited `GitStatusEvent`: `content` (open/applied/closed/draft) |
|
||
| 1808 | AudioHeaderEvent | experimental/audio/header | `content` |
|
||
| 1985 | LabelEvent | nip32Labeling | `(listOf(content) + labels().map { it.label }).filter { it.isNotEmpty() }` NL |
|
||
| 2003 | TorrentEvent | nip35Torrents | `(listOfNotNull(title(), content) + fileNames())` NL — the `file` tags' paths |
|
||
| 2004 | TorrentCommentEvent | nip35Torrents | `content` |
|
||
| 2473 | BirdDetectionEvent | experimental/birdstar | `listOfNotNull(summary(), speciesName())` NL |
|
||
| 3302 | ConcordChatEditEvent | concord/cord03Channels | `content` |
|
||
| 5050 | DvmTextGenerationRequestEvent | nip90Dvms/textGeneration | `inputs().filter { it.type == "prompt" \|\| it.type == "text" }.joinToString(" ") { it.value }` (SP) |
|
||
| 5100 | DvmImageGenerationRequestEvent | nip90Dvms/imageGeneration | `listOfNotNull(prompt(), negativePrompt()).joinToString(" ")` (SP) |
|
||
| 5128 | SiteSnapshotEvent | nip5aStaticWebsites | `listOfNotNull(title(), description())` NL |
|
||
| 5129 | NappletSnapshotEvent | nip5dNapplets | `listOfNotNull(title(), description())` NL |
|
||
| 5250 | DvmTextToSpeechRequestEvent | nip90Dvms/textToSpeech | `text() ?: ""` |
|
||
| 5302 | DvmContentSearchRequestEvent | nip90Dvms/contentSearch | `searchQuery() ?: ""` |
|
||
| 5303 | DvmPeopleSearchRequestEvent | nip90Dvms/peopleSearch | `searchQuery() ?: ""` |
|
||
| 5901 | DvmOpReturnRequestEvent | nip90Dvms/opReturn | `text() ?: ""` |
|
||
| 6969 | ZapPollEvent | experimental/zapPolls | `buildString { append(content); pollOptionsArray().forEach { append('\n').append(it.descriptor) } }` |
|
||
| 7516 | GeocacheFoundLogEvent | nipCCGeocaching/foundLog | `content` |
|
||
| 8002 | ArchivedIdentityEvent | buzz/iaIdentityArchival | `content` |
|
||
| 8003 | UnarchivedIdentityEvent | buzz/iaIdentityArchival | `content` |
|
||
| 8333 | OnchainZapEvent | nipBCOnchainZaps/zap | `content` |
|
||
| 9002 | GroupEditMetadataEvent | nip29RelayGroups/moderation | `(listOfNotNull(name(), about()) + hashtags())` NL |
|
||
| 9007 | CreateGroupEvent | nip29RelayGroups/moderation | `listOfNotNull(name(), about())` NL |
|
||
| 9021 | GroupJoinRequestEvent | nip29RelayGroups/request | `content` |
|
||
| 9022 | GroupLeaveRequestEvent | nip29RelayGroups/request | `content` |
|
||
| 9035 | ArchiveRequestEvent | buzz/iaIdentityArchival | `content` |
|
||
| 9036 | UnarchiveRequestEvent | buzz/iaIdentityArchival | `content` |
|
||
| 9041 | ZapGoalEvent | nip75ZapGoals | `listOfNotNull(summary(), content)` NL |
|
||
| 9321 | NutzapEvent | nip61Nutzaps/nutzap | `content` |
|
||
| 9734 | ZapRequestEvent | nip57Zaps | `content` |
|
||
| 9735 | ZapReceiptEvent | nip57Zaps | `zapRequest?.content.orEmpty()` — indexes the **embedded 9734's** content |
|
||
| 9736 | Bolt12ZapEvent | nipB1Bolt12Zaps/zap | `content` |
|
||
| 9737 | Bolt12ZapIntentEvent | nipB1Bolt12Zaps/intent | `content` |
|
||
| 9802 | HighlightEvent | nip84Highlights | `listOfNotNull(comment(), searchableContext(), content)` NL — `searchableContext()` is the `context` tag, else a `textquoteselector`'s prefix and suffix (whitespace-collapsed, space-joined) |
|
||
| 9998 | ListHeaderEvent | experimental/decentralizedLists/header | `tags.searchableListContent()` NL — `names` (singular, plural), `titles` (singular, plural), `name`, `title`, `description`, `comments`, then in tag order every `t` value that is not `isMachineValue` and every value of every other tag (except `alt`, `client`, `imeta`) that passes `isNaturalLanguageValue` (has whitespace or non-ASCII, or is one capitalized letters-only word; never JSON, numbers, URIs of any scheme, addresses, hex ids, UUIDs, bech32) |
|
||
| 9999 | ListItemEvent | experimental/decentralizedLists/item | same as 9998 |
|
||
| 10003 | BookmarkListEvent | nip51Lists/bookmarkList | `listOfNotNull(titleOrName())` NL |
|
||
| 10100 | AgentProfileEvent | buzz/agentProfiles | `profileOrNull()?.let { listOfNotNull(it.name, it.displayName).joinToString("\n") } ?: ""` |
|
||
| 10154 | PodcastMetadataEvent | nipF4Podcasts/metadata | `listOfNotNull(title(), description())` NL |
|
||
| 11316 | CvmServerAnnouncementEvent | contextvm/cep06Announcements | `listOfNotNull(serverName(), about())` NL (class lives in `CvmAnnouncementEvents.kt`) |
|
||
| 11333 | SnoAvatarEvent | cyberspace/deck0003Sno | `nameTag().orEmpty()` — the `name` tag only; `content` is SNO geometry JSON |
|
||
| 11871 | AttestorProficiencyEvent | experimental/attestations/proficiency | `listOfNotNull(description())` NL |
|
||
| 12473 | BirdexEvent | experimental/birdstar | `(listOfNotNull(summary()) + speciesNames())` NL |
|
||
| 15128 | RootSiteEvent | nip5aStaticWebsites | `listOfNotNull(title(), description())` NL |
|
||
| 15129 | RootNappletEvent | nip5dNapplets | `listOfNotNull(title(), description())` NL |
|
||
| 30000 | FollowSetEvent | nip51Lists/followSet | `listOfNotNull(titleOrName(), description())` NL |
|
||
| 30001 | OldBookmarkListEvent | nip51Lists/bookmarkList | `listOfNotNull(title())` NL |
|
||
| 30002 | RelaySetEvent | nip51Lists/relaySets | `listOfNotNull(title(), description())` NL |
|
||
| 30003 | BookmarkSetEvent | nip51Lists/bookmarkSet | `listOfNotNull(titleOrName(), description())` NL |
|
||
| 30004 | ArticleCurationSetEvent | nip51Lists/articleCurationSet | `listOfNotNull(title(), description())` NL |
|
||
| 30005 | VideoCurationSetEvent | nip51Lists/videoCurationSet | `listOfNotNull(title(), description())` NL |
|
||
| 30006 | PictureCurationSetEvent | nip51Lists/pictureCurationSet | `listOfNotNull(title(), description())` NL |
|
||
| 30008 | AcceptedBadgeSetEvent | nip58Badges/accepted | `listOfNotNull(title(), description())` NL |
|
||
| 30009 | BadgeDefinitionEvent | nip58Badges/definition | `listOfNotNull(name(), description(), content)` NL |
|
||
| 30015 | InterestSetEvent | nip51Lists/interestSet | `(listOfNotNull(title(), description()) + publicHashtags())` NL |
|
||
| 30017 | StallEvent | nip15Marketplace/stall | `stallData()?.let { listOfNotNull(it.name, it.description).joinToString("\n") } ?: ""` |
|
||
| 30018 | ProductEvent | nip15Marketplace/product | `productData()?.let { (listOfNotNull(it.name, it.description) + categories()).joinToString("\n") } ?: ""` |
|
||
| 30019 | MarketplaceEvent | nip15Marketplace/marketplace | `marketplaceData()?.let { listOfNotNull(it.name, it.about).joinToString("\n") } ?: ""` |
|
||
| 30020 | AuctionEvent | nip15Marketplace/auction | `auctionData()?.let { (listOfNotNull(it.name, it.description) + tags.hashtags()).joinToString("\n") } ?: ""` |
|
||
| 30023 | LongFormContentEvent | nip23LongContent | `(listOfNotNull(title(), summary(), content) + topics())` NL |
|
||
| 30024 | LongFormDraftEvent | nip23LongContent/draft | `tags.longFormIndexableContent(content)` — the same as 30023: `(listOfNotNull(title(), summary(), content) + topics())` NL |
|
||
| 30030 | EmojiPackEvent | nip30CustomEmoji/pack | `(listOfNotNull(titleOrName(), description()) + publicEmojiCodes())` NL — the public `emoji` tags' shortcodes; `content` is NOT indexed (it is the NIP-44 ciphertext of the private emoji tags) |
|
||
| 30031 | StickerPackEvent | nip30CustomEmoji/stickers | `(listOfNotNull(title(), description()) + stickers().map { it.code })` NL (never `content`) |
|
||
| 30040 | PublicationIndexEvent | experimental/publications | `listOfNotNull(title(), author(), summary())` NL |
|
||
| 30041 | PublicationContentEvent | experimental/publications | `listOfNotNull(title(), content)` NL |
|
||
| 30045 | BookshelfDirectoryEvent | experimental/library | `listOfNotNull(title(), summary(), content)` NL |
|
||
| 30054 | Podcasting20EpisodeEvent | nipXXPodcasting20/episode | `(listOfNotNull(title(), description(), content) + personNames() + soundbiteTitles() + topics())` NL |
|
||
| 30055 | Podcasting20TrailerEvent | nipXXPodcasting20/trailer | `listOfNotNull(title(), content)` NL |
|
||
| 30063 | ReleaseArtifactSetEvent † | nip51Lists/releaseArtifactSet | `listOfNotNull(title(), description(), searchableReleaseNotes())` NL |
|
||
| 30066 | LiveChessMoveEvent | nip64Chess/move | `content` |
|
||
| 30068 | LiveChessDrawOfferEvent | nip64Chess/draw | `content` |
|
||
| 30142 | LearningResourceEvent | experimental/library | `(listOfNotNull(title(), alternateTitle(), summary(), alternateSummary(), content, author()) + facetLabels())` NL — `facetLabels()` = resource types, educational levels, subjects, deduplicated |
|
||
| 30175 | PersonaEvent | buzz/apPersonas | `personaOrNull()?.let { listOfNotNull(it.displayName, it.description, it.systemPrompt).joinToString("\n") } ?: ""` |
|
||
| 30176 | TeamEvent | buzz/teams | `teamOrNull()?.let { listOfNotNull(it.name, it.description, it.instructions).joinToString("\n") } ?: ""` |
|
||
| 30177 | ManagedAgentEvent | buzz/managedAgents | `agentOrNull()?.let { listOfNotNull(it.name, it.systemPrompt).joinToString("\n") } ?: ""` |
|
||
| 30178 | TeamCatalogEvent | buzz/teamCatalog | `catalogOrNull()?.let { catalog -> buildList { add(catalog.name); catalog.description?.let(::add); catalog.instructions?.let(::add); catalog.members.forEach { member -> add(member.displayName); member.systemPrompt?.let(::add) } }.joinToString("\n") } ?: ""` |
|
||
| 30267 | AppCurationSetEvent | nip51Lists/appCurationSet | `listOfNotNull(titleOrName(), description())` NL |
|
||
| 30296 | InteractiveStoryPrologueEvent | experimental/interactiveStories | inherited base: `(listOfNotNull(title(), summary(), content) + optionLabels())` NL |
|
||
| 30297 | InteractiveStorySceneEvent | experimental/interactiveStories | inherited base: `(listOfNotNull(title(), summary(), content) + optionLabels())` NL |
|
||
| 30301 | KanbanBoardEvent ¶ | experimental/kanban/board | `listOfNotNull(title(), description())` NL |
|
||
| 30301 | BuildVerificationEvent ¶ | experimental/walletScrutiny/verification | `listOfNotNull(description(), report())` NL (both from the JSON `content`) |
|
||
| 30302 | KanbanCardEvent ¶ | experimental/kanban/card | `listOfNotNull(title(), description())` NL |
|
||
| 30311 | LiveActivitiesEvent | nip53LiveActivities/streaming | `listOfNotNull(title(), summary(), content)` NL |
|
||
| 30312 | MeetingSpaceEvent | nip53LiveActivities/meetingSpaces | `listOfNotNull(room(), summary(), content)` NL |
|
||
| 30313 | MeetingRoomEvent | nip53LiveActivities/meetingSpaces | `listOfNotNull(title(), summary())` NL |
|
||
| 30315 | UserStatusEvent | nip38UserStatus | `content` |
|
||
| 30382 | UserAssertionEvent | nip85TrustedAssertions/users | `(listOfNotNull(petName(), summary()) + topics())` NL — public tags only, never the NIP-44 content |
|
||
| 30392 | UserTrustedListEvent | experimental/trustedLists/users | inherited `TrustedListEvent`: `title() ?: ""` — the label only; `metric`/`d` are machine ids and `content` is a JSON echo of the membership |
|
||
| 30393 | EventTrustedListEvent | experimental/trustedLists/events | inherited `TrustedListEvent`: `title() ?: ""` |
|
||
| 30394 | AddressableTrustedListEvent | experimental/trustedLists/addressables | inherited `TrustedListEvent`: `title() ?: ""` |
|
||
| 30395 | ExternalIdTrustedListEvent | experimental/trustedLists/externalIds | inherited `TrustedListEvent`: `title() ?: ""` |
|
||
| 30402 | ClassifiedsEvent | nip99Classifieds | `(listOfNotNull(title(), summary(), content, location()) + categories())` NL |
|
||
| 30617 | GitRepositoryEvent | nip34Git/repository | `(listOfNotNull(name(), description(), content) + hashtags())` NL |
|
||
| 30620 | WorkflowDefEvent | buzz/workflow | `listOfNotNull(name(), content)` NL |
|
||
| 30621 | ProjectEvent | buzz/mpProjects | `listOfNotNull(displayName(), description())` NL |
|
||
| 30817 | NipTextEvent | experimental/nipsOnNostr | `listOfNotNull(title(), content)` NL |
|
||
| 30818 | WikiArticleEvent | nip54Wiki | `listOfNotNull(title(), summary(), content)` NL |
|
||
| 31337 | AudioTrackEvent | experimental/audio/track | `listOfNotNull(subject())` NL |
|
||
| 31871 | AttestationEvent | experimental/attestations/attestation | `content` |
|
||
| 31872 | AttestationRequestEvent | experimental/attestations/request | `content` |
|
||
| 31873 | AttestorRecommendationEvent | experimental/attestations/recommendation | `listOfNotNull(description())` NL |
|
||
| 31890 | FeedDefinitionEvent | feedDefinition | `title().orEmpty()` (now registered in `EventFactory`; before that it parsed as a plain `Event` and was never searched) |
|
||
| 31922 | CalendarDateSlotEvent | nip52Calendar/appt/day | `(listOfNotNull(title(), summary(), content) + locations() + hashtags())` NL |
|
||
| 31923 | CalendarTimeSlotEvent | nip52Calendar/appt/time | `(listOfNotNull(title(), summary(), content) + locations() + hashtags())` NL |
|
||
| 31924 | CalendarCollectionEvent | nip52Calendar/calendar | `listOfNotNull(title(), content)` NL |
|
||
| 31925 | CalendarRSVPEvent | nip52Calendar/rsvp | `content` |
|
||
| 31987 | RelayReviewEvent | experimental/ratings | `content` |
|
||
| 31990 | AppDefinitionEvent | nip89AppHandlers/definition | `appMetaData()?.let { listOfNotNull(it.name, it.username, it.displayName, it.about, it.nip05, it.lud06, it.lud16, it.website, it.picture, it.banner, it.image).joinToString(" ") } ?: ""` (SP) |
|
||
| 32176 | BlossomPieceIndexEvent | experimental/library | `listOfNotNull(title(), summary(), content)` NL |
|
||
| 32267 | SoftwareApplicationEvent | experimental/nip82SoftwareApps/application | `listOfNotNull(name(), summary(), content)` NL |
|
||
| 33331 | SnoObjectEvent | cyberspace/deck0003Sno | `nameTag().orEmpty()` — the `name` tag only; `content` is SNO geometry JSON |
|
||
| 33401 | ExerciseTemplateEvent | experimental/fitness/workout | `listOfNotNull(title(), content)` NL |
|
||
| 33402 | WorkoutTemplateEvent | experimental/fitness/workout | `listOfNotNull(title(), content)` NL |
|
||
| 33534 | RelayRoleEvent | nip43RelayMembers/roles | `listOfNotNull(label(), description())` NL |
|
||
| 33863 | FundraiserEvent | experimental/agora | `listOfNotNull(title(), content)` NL |
|
||
| 34139 | MusicPlaylistEvent | experimental/music/playlist | `listOfNotNull(title(), description(), content)` NL |
|
||
| 34235 | AddressableNormalVideoEvent | nip71Video | inherited `AddressableVideoEvent`: `(listOfNotNull(title(), content) + segmentTitles())` NL |
|
||
| 34236 | AddressableShortVideoEvent | nip71Video | inherited `AddressableVideoEvent`: `(listOfNotNull(title(), content) + segmentTitles())` NL |
|
||
| 34259 | EntityRatingEvent | experimental/ratings | `content` |
|
||
| 34550 | CommunityDefinitionEvent | nip72ModCommunities/definition | `listOfNotNull(name(), description(), rules(), content)` NL |
|
||
| 35128 | NamedSiteEvent | nip5aStaticWebsites | `listOfNotNull(title(), description())` NL |
|
||
| 35129 | NamedNappletEvent | nip5dNapplets | `listOfNotNull(title(), description())` NL |
|
||
| 36767 | ThemeDefinitionEvent | experimental/profileTheme/definition | `listOfNotNull(title(), description())` NL (never the colors, fonts or URLs) |
|
||
| 36787 | MusicTrackEvent | experimental/music/track | `listOfNotNull(title(), artist(), album(), content)` NL |
|
||
| 37516 | GeocacheListingEvent | nipCCGeocaching/listing | `listOfNotNull(cacheName(), content)` NL (the `hint` is deliberately not indexed — matching a hint is spoiling it) |
|
||
| 37517 | GeocacheCurationListEvent | nipCCGeocaching/curation | `listOfNotNull(title(), description(), content)` NL |
|
||
| 38000 | MintRecommendationEvent ‡ | nip87Ecash/recommendation | `content` |
|
||
| 38000 | BallotEvent ‡ | experimental/ballots | `buildList { election()?.let { add(it) }; answers().forEach { add(it.answer) } }` NL |
|
||
| 38000 | PredictionMarketEvent ‡ | experimental/predictionMarkets | `(listOfNotNull(title(), description()) + outcomes() + listOfNotNull(resolution(), cancelReason(), socialPost()))` NL |
|
||
| 38192 | Ps1SaveEvent | experimental/ps1saves | `listOfNotNull(summary(), saveTitle(), region(), filename())` NL |
|
||
| 38383 | P2POrderEvent | nip69P2pOrderEvents | `(listOfNotNull(makerName(), currency()) + paymentMethods().orEmpty()).joinToString(" ")` (SP) |
|
||
| 38385 | MostroInfoEvent § | nip69P2pOrderEvents/mostroInfo | `(listOfNotNull(instanceName()) + fiatCurrenciesAccepted().orEmpty()).joinToString(" ")` (SP) |
|
||
| 39000 | GroupMetadataEvent | nip29RelayGroups/metadata | `(listOfNotNull(name(), about()) + hashtags())` NL |
|
||
| 39003 | GroupRolesEvent | nip29RelayGroups/metadata | `roles().flatMap { listOfNotNull(it.name, it.description) }` NL |
|
||
| 39089 | StarterPackEvent | nip51Lists/starterPack | `(listOfNotNull(title(), description()) + hashtags())` NL |
|
||
| 39092 | MediaStarterPackEvent | nip51Lists/mediaStarterPack | `listOfNotNull(title(), description())` NL |
|
||
| 39307 | TextTrackEvent | nip71Video/textTrack | `if (WebVttText.hasCues(content)) WebVttText.cueText(content) else content` — `cueText` is each cue's payload lines (NL) with tags removed and character references decoded; no header, timings, cue settings, ids, `NOTE`/`STYLE`/`REGION` blocks. Content with no `-->` timing line is not a caption file and is indexed as written |
|
||
| 39701 | WebBookmarkEvent | nipB0WebBookmarks | `(listOfNotNull(title(), description()) + hashtags())` NL |
|
||
| 39998 | AddressableListHeaderEvent | experimental/decentralizedLists/header | same as 9998 |
|
||
| 39999 | AddressableListItemEvent | experimental/decentralizedLists/item | same as 9998 |
|
||
| 40002 | StreamMessageV2Event | buzz/stream | `content` |
|
||
| 40003 | StreamMessageEditEvent | buzz/stream | `content` |
|
||
| 40006 | StreamMessageScheduledEvent | buzz/stream | `content` |
|
||
| 40007 | StreamReminderEvent | buzz/stream | `content` |
|
||
| 40008 | StreamMessageDiffEvent | buzz/stream | `description() ?: ""` — the `description` tag; the body is a unified diff and stays out |
|
||
| 40099 | SystemMessageEvent | buzz/stream | `payload()?.let { listOfNotNull(it.topic, it.purpose, it.publicReason).joinToString("\n") } ?: ""` — fields of the JSON content |
|
||
| 40100 | CanvasEvent | buzz/stream | `content` |
|
||
| 40901 | ChannelSummaryEvent | buzz/stream/sidecars | `summary()?.let { listOfNotNull(it.name, it.about, it.topic, it.purpose).joinToString("\n") } ?: ""` — fields of the JSON content |
|
||
| 42000 | ProductFeedbackEvent | buzz/moderation | `content` |
|
||
| 43001 | JobRequestEvent | buzz/jobs | `content` |
|
||
| 43002 | JobAcceptedEvent | buzz/jobs | `content` |
|
||
| 43003 | JobProgressEvent | buzz/jobs | `content` |
|
||
| 43004 | JobResultEvent | buzz/jobs | `content` |
|
||
| 43005 | JobCancelEvent | buzz/jobs | `content` |
|
||
| 43006 | JobErrorEvent | buzz/jobs | `content` |
|
||
| 45001 | ForumPostEvent | buzz/forum | `content` |
|
||
| 45003 | ForumCommentEvent | buzz/forum | `content` |
|
||
| 45010 | ArtifactEvent | buzz/arArtifacts | `listOfNotNull(title(), textBody())` NL — `textBody()` is `content` unless blank or JSON (starts with `{`/`[`) |
|
||
| 46030 | ApprovalGrantEvent | buzz/workflow | `content` |
|
||
| 46031 | ApprovalDenyEvent | buzz/workflow | `content` |
|
||
| 48106 | HuddleGuidelinesEvent | buzz/huddles | `content` |
|
||
|
||
† **Kind 30063 is shared** by NIP-51 release artifact sets and NIP-82 software releases, and
|
||
`ReleaseArtifactSetEvent` parses both. It indexes `title()` and `description()`, plus `content`
|
||
(the release notes, via `searchableReleaseNotes()`) only when it is non-blank and the event
|
||
carries the NIP-82 `i` + `version` tags — a NIP-51 set may hold encrypted private items in
|
||
`content`, which must never be indexed.
|
||
|
||
‡ **Kind 38000 is shared** by NIP-87 mint recommendations and two app formats, and `EventFactory`
|
||
picks the class by tags: `MintRecommendationEvent` when any `k` is 38172/38173 (or, with no
|
||
`k`, a non-blank `u` or an `a` to a 38172/38173 address); else `BallotEvent` on a non-blank
|
||
`election`; else `PredictionMarketEvent` on a `market`, ≥2 `outcome`s, or `type` + `end`; else
|
||
`UnrecognizedKind38000Event` — addressable (stores still key it by `d`) but unsearchable (the
|
||
spam votes that make up most of the kind). Kind-level probes (`EventFactory.probe`) answer as
|
||
`MintRecommendationEvent`. A market's `title()`/`description()` come from its `data` tag JSON,
|
||
the `title` tag, or JSON `content`, in that order; it also indexes its outcome labels, the
|
||
resolution, the cancel reason, and `content` as `socialPost()` when it is a non-blank, non-JSON post
|
||
and the market has no `description()` it would merely repeat.
|
||
|
||
§ **Kind 38385 is shared** by Mostro instance info and other apps (Paygress lease revocations,
|
||
bond-trade assignments, game scores). `EventFactory` builds `MostroInfoEvent` only when a `z` of
|
||
`info` or a `mostro_version` tag is present, else `UnrecognizedKind38385Event` — addressable but
|
||
unsearchable. Kind-level probes answer as `MostroInfoEvent`. Mostro's 38384 / 38386 and RoboSats'
|
||
31986 are split the same way, but none of their classes is searchable.
|
||
|
||
¶ **Kind 30301 is shared** by Kanban boards (NIP PR #1665), WalletScrutiny reproducible-build
|
||
verifications and an encrypted planner app. `EventFactory` builds `BuildVerificationEvent` when a
|
||
non-blank `i` and `status` are present, else `KanbanBoardEvent` on a non-blank `title` or a `col`
|
||
with a name, else `UnrecognizedKind30301Event` — addressable but unsearchable (the planner's
|
||
NIP-44 tasks). Kind-level probes answer as `KanbanBoardEvent`. A verification indexes the
|
||
`description` and the markdown report (`content`) of its JSON `content`. Kind 30302 is split the
|
||
same way: `KanbanCardEvent` on a `title` or an `a` to a 30301 board, else
|
||
`UnrecognizedKind30302Event` (Fieldbook team memberships).
|
||
|
||
## Abstract bases (no kind of their own)
|
||
|
||
| Base class | Body | Concrete kinds |
|
||
|---|---|---|
|
||
| `CitationEvent` | `listOfNotNull(title(), summary(), content, author(), publishedBy())` NL | 31 (32 and 33 override with their extra fields) |
|
||
| `GitStatusEvent` | `content` | 1630, 1631, 1632, 1633 |
|
||
| `InteractiveStoryBaseEvent` | `(listOfNotNull(title(), summary(), content) + optionLabels())` NL — the non-blank `option` choice texts | 30296, 30297 |
|
||
| `AddressableVideoEvent` | `(listOfNotNull(title(), content) + segmentTitles())` NL — the `segment` tags' titles | 34235, 34236 |
|
||
| `RegularVideoEvent` | `(listOfNotNull(title(), content) + segmentTitles())` NL | 21, 22 |
|
||
| `TrustedListEvent` | `title() ?: ""` | 30392, 30393, 30394, 30395 |
|
||
|
||
## How to regenerate / verify this table
|
||
|
||
```bash
|
||
# The authoritative kind set (sorted, one comment per kind naming the class):
|
||
cat quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip50Search/SearchableKinds.kt
|
||
# All implementor files:
|
||
grep -rln "override fun indexableContent" quartz/src/commonMain
|
||
# For each, pair the KIND constant with the indexableContent() body.
|
||
# Searchability on the store path additionally requires EventFactory registration:
|
||
grep -n "<ClassName>" quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/EventFactory.kt
|
||
```
|
||
|
||
Two tests keep the code side from drifting: `SearchableKindsTest` (commonTest) builds every kind
|
||
0–65535 through `EventFactory` and asserts the searchable ones are exactly `SearchableKinds.ALL`,
|
||
and `IndexableContentGoldenTest` (jvmTest) records each kind's `indexableContent()` for a
|
||
tag-rich sample event in `quartz/src/jvmTest/resources/indexable-content.golden` — a CI-diffable
|
||
snapshot. Diff `SearchableKinds.kt` and the golden file at a version bump; this table is still
|
||
updated by hand.
|