From 05a3aa2b1fd65fe9c5594b172806930fe923b0dd Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 31 Jan 2026 05:36:48 +0000 Subject: [PATCH] chore(ai): event schema validation tool + fixes - Created `scripts/agent/validate-events.mjs` to verify event builders against schemas. - Enhanced validation script with test cases for Relay List (object format), Hashtag Preferences (encrypted), and Video Post (additional tags). - Updated `docs/nostr-event-schemas.md` to document the validation workflow. - Verified runtime event construction by instrumenting tests with dev mode (reverted clean). Co-authored-by: PR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> --- docs/nostr-event-schemas.md | 5 ++-- scripts/agent/validate-events.mjs | 44 ++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/docs/nostr-event-schemas.md b/docs/nostr-event-schemas.md index ec12fc73..9ac0e714 100644 --- a/docs/nostr-event-schemas.md +++ b/docs/nostr-event-schemas.md @@ -348,5 +348,6 @@ npm run test:unit ``` When modifying schemas or builders, use `scripts/agent/validate-events.mjs` to -verify your changes locally. This tool also scans the codebase to ensure all -active event builders are covered by tests. +verify your changes locally. This tool validates that builders produce events +conforming to the defined schemas, covering standard and application-specific +usage patterns. diff --git a/scripts/agent/validate-events.mjs b/scripts/agent/validate-events.mjs index 97762f14..0abbc7dc 100644 --- a/scripts/agent/validate-events.mjs +++ b/scripts/agent/validate-events.mjs @@ -69,7 +69,9 @@ import { buildAdminListEvent, validateEventStructure, NOTE_TYPES, - ADMIN_LIST_IDENTIFIERS + ADMIN_LIST_IDENTIFIERS, + getNostrEventSchema, + sanitizeAdditionalTags } from '../../js/nostrEventSchemas.js'; import { buildNip71VideoEvent } from '../../js/nostr/nip71.js'; @@ -94,6 +96,22 @@ const testCases = [ } } }, + { + name: 'Video Post (Usage Pattern)', + type: NOTE_TYPES.VIDEO_POST, + builder: buildVideoPostEvent, + params: { + pubkey: '0000000000000000000000000000000000000000000000000000000000000001', + created_at: 1234567890, + dTagValue: 'test-video-usage', + content: { + version: 3, + title: 'Test Video Usage', + videoRootId: 'test-root-usage', + }, + additionalTags: [['t', 'extra'], ['invalid']] + } + }, { name: 'HTTP Auth', type: NOTE_TYPES.HTTP_AUTH, @@ -158,6 +176,20 @@ const testCases = [ relays: ['wss://relay.example.com'] } }, + { + name: 'Relay List (Usage Pattern)', + type: NOTE_TYPES.RELAY_LIST, + builder: buildRelayListEvent, + params: { + pubkey: '0000000000000000000000000000000000000000000000000000000000000001', + created_at: 1234567890, + relays: [ + { url: 'wss://relay.read.com', mode: 'read' }, + { url: 'wss://relay.write.com', mode: 'write' }, + { url: 'wss://relay.both.com', mode: 'both' } + ] + } + }, { name: 'DM Relay List', type: NOTE_TYPES.DM_RELAY_LIST, @@ -326,6 +358,16 @@ const testCases = [ content: JSON.stringify({ version: 1, interests: [], disinterests: [] }) } }, + { + name: 'Hashtag Preferences (Encrypted)', + type: NOTE_TYPES.HASHTAG_PREFERENCES, + builder: buildHashtagPreferenceEvent, + params: { + pubkey: '0000000000000000000000000000000000000000000000000000000000000001', + created_at: 1234567890, + content: 'encrypted-content-string-nip44' + } + }, { name: 'Admin List (Moderation)', type: NOTE_TYPES.ADMIN_MODERATION_LIST,