mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
feat(agents): Execute nip-research-agent (NIP-65 compliance)
- Create tests/nostr-specs/nip65_compliance.test.mjs to verify Kind 10002 behavior - Update NIP_INVENTORY.md status for NIP-65 (Partial -> Compliant) - Generate nip-report-2026-02-18.md - Add agent state files (context, todo, decisions, test_logs) - Add completion log in docs/agents/task-logs/daily/ Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
1 parent
f57eef19c9
commit
3f3598cb63
8 files changed
+207
-1
No files matched your search
+1
-1
@@ -17,7 +17,7 @@
|
|||||||
| **NIP-56** | Reporting | `js/services/moderationService.js`, `docs/nips/56.md` | Compliant | `buildReportEvent` implements Kind 1984. |
|
| **NIP-56** | Reporting | `js/services/moderationService.js`, `docs/nips/56.md` | Compliant | `buildReportEvent` implements Kind 1984. |
|
||||||
| **NIP-57** | Zaps | `js/payments/zapRequests.js`, `js/payments/zapSplit.js` | Compliant | Implements Kind 9734/9735 flow. |
|
| **NIP-57** | Zaps | `js/payments/zapRequests.js`, `js/payments/zapSplit.js` | Compliant | Implements Kind 9734/9735 flow. |
|
||||||
| **NIP-59** | Gift Wrap | `js/nostr/client.js` | Compliant | Implemented as part of NIP-17. |
|
| **NIP-59** | Gift Wrap | `js/nostr/client.js` | Compliant | Implemented as part of NIP-17. |
|
||||||
| **NIP-65** | Relay List Metadata | `js/relayManager.js` | Partial | Code supports Kind 10002. Test `nip65_compliance.test.mjs` is missing. |
|
| **NIP-65** | Relay List Metadata | `js/relayManager.js` | Compliant | Code supports Kind 10002. Verified by `tests/nostr-specs/nip65_compliance.test.mjs`. |
|
||||||
| **NIP-71** | Video Events | `js/nostr/nip71.js` | Partial | Kinds 21/22 supported in schema, but Kind 30078 is primary. Verified tag generation in `tests/nostr-specs/kind30078.test.mjs`. |
|
| **NIP-71** | Video Events | `js/nostr/nip71.js` | Partial | Kinds 21/22 supported in schema, but Kind 30078 is primary. Verified tag generation in `tests/nostr-specs/kind30078.test.mjs`. |
|
||||||
| **NIP-78** | Application-specific data | `js/services/hashtagPreferencesService.js` | Compliant | Used for hashtag preferences (Kind 30015). |
|
| **NIP-78** | Application-specific data | `js/services/hashtagPreferencesService.js` | Compliant | Used for hashtag preferences (Kind 30015). |
|
||||||
| **NIP-94** | File Metadata | `js/nostr/videoPublisher.js` | Compliant | `buildVideoMirrorEvent` implements Kind 1063. |
|
| **NIP-94** | File Metadata | `js/nostr/videoPublisher.js` | Compliant | `buildVideoMirrorEvent` implements Kind 1063. |
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Context: NIP Research Agent Run (2026-02-18)
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
Execute the daily `nip-research-agent` task to research NIPs, verify compliance, and update the inventory.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
- Focus on NIP-65 / Kind 10002 compliance verification.
|
||||||
|
- Implement missing tests for `relayManager.js`.
|
||||||
|
- Update `NIP_INVENTORY.md`.
|
||||||
|
|
||||||
|
## Definition of Done
|
||||||
|
- `tests/nostr-specs/nip65_compliance.test.mjs` created and passing.
|
||||||
|
- `NIP_INVENTORY.md` updated.
|
||||||
|
- Completion log submitted.
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# Decisions: NIP Research Agent (2026-02-18)
|
||||||
|
|
||||||
|
- **Prioritize NIP-65**: The inventory lists NIP-65 as "Partial" due to missing tests. As a P0 item (Relay Lists), this is the highest priority gap to close.
|
||||||
|
- **Test Strategy**: Create a new test file `tests/nostr-specs/nip65_compliance.test.mjs` that mocks `nostrClient` to test `relayManager` in isolation.
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Daily Task: nip-research-agent
|
||||||
|
|
||||||
|
- **Date**: 2026-02-18
|
||||||
|
- **Agent**: nip-research-agent
|
||||||
|
- **Status**: Completed
|
||||||
|
- **Output**:
|
||||||
|
- Created `tests/nostr-specs/nip65_compliance.test.mjs` (verified NIP-65/Kind 10002).
|
||||||
|
- Updated `NIP_INVENTORY.md` (NIP-65 -> Compliant).
|
||||||
|
- Created `nip-report-2026-02-18.md`.
|
||||||
|
- Updated agent state files in `context/`, `todo/`, `decisions/`, `test_logs/`.
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
- Ran `npm test -- tests/nostr-specs/nip65_compliance.test.mjs`: PASSED.
|
||||||
|
- Ran `npm run lint`: PASSED.
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# NIP Compliance Report (2026-02-18)
|
||||||
|
|
||||||
|
## Executive Summary
|
||||||
|
This run focused on closing the compliance gap for **NIP-65 (Relay List Metadata)**, identified as a P0 priority. A new regression test suite `tests/nostr-specs/nip65_compliance.test.mjs` was created to verify `relayManager.js` behavior against Kind 10002 specifications. The test confirms correct parsing of relay tags (including read/write markers) and correct event building.
|
||||||
|
|
||||||
|
## Changes
|
||||||
|
- **NIP-65**: Status upgraded from `Partial` to `Compliant`.
|
||||||
|
- **Tests**: Added `tests/nostr-specs/nip65_compliance.test.mjs`.
|
||||||
|
|
||||||
|
## Compliance Status (Snapshot)
|
||||||
|
- **Compliant**: NIP-01, NIP-04, NIP-07, NIP-10, NIP-17, NIP-19, NIP-33, NIP-44, NIP-46, NIP-51, NIP-56, NIP-57, NIP-59, NIP-65, NIP-78, NIP-94, NIP-98, NIP-25, NIP-47.
|
||||||
|
- **Partial**: NIP-09 (Event Deletion - incomplete Kind 5), NIP-71 (Video Events - mixed Kind 30078/21/22), NIP-96 (HTTP File Storage).
|
||||||
|
- **Unknown**: NIP-21 (URI Scheme), NIP-42 (Auth).
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
- **NIP-42 (Auth)**: Verify authentication flow (RELAY AUTH).
|
||||||
|
- **NIP-96**: Investigate HTTP File Storage integration status.
|
||||||
|
- **NIP-71**: Clarify path forward for standard vs legacy video kinds.
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# Test Log: NIP Research Agent (2026-02-18)
|
||||||
|
|
||||||
|
## Execution
|
||||||
|
Ran `node scripts/run-unit-tests.mjs tests/nostr-specs/nip65_compliance.test.mjs`.
|
||||||
|
|
||||||
|
## Results
|
||||||
|
- `tests/nostr-specs/nip65_compliance.test.mjs` PASSED.
|
||||||
|
- Verified NIP-65 parsing (relay list events).
|
||||||
|
- Verified NIP-65 event building (Kind 10002).
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
- Mocked `nostrClient` and `setActiveSigner` to simulate environment.
|
||||||
|
- Used `local` signer type to bypass extension permissions in test.
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
import { test, describe, it, before, after, beforeEach } from 'node:test';
|
||||||
|
import assert from 'node:assert';
|
||||||
|
import { relayManager } from '../../js/relayManager.js';
|
||||||
|
import { nostrClient, setActiveSigner } from '../../js/nostrClientFacade.js';
|
||||||
|
|
||||||
|
// Mock browser globals
|
||||||
|
if (typeof globalThis.window === 'undefined') {
|
||||||
|
globalThis.window = {
|
||||||
|
location: { protocol: 'https:' },
|
||||||
|
localStorage: {
|
||||||
|
getItem: () => null,
|
||||||
|
setItem: () => {},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('NIP-65 / Kind 10002 Compliance', () => {
|
||||||
|
let originalPool;
|
||||||
|
let originalSigner;
|
||||||
|
|
||||||
|
before(() => {
|
||||||
|
// Save original state
|
||||||
|
originalPool = nostrClient.pool;
|
||||||
|
});
|
||||||
|
|
||||||
|
after(() => {
|
||||||
|
// Restore original state
|
||||||
|
nostrClient.pool = originalPool;
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
relayManager.reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse NIP-65 relay list events correctly', async () => {
|
||||||
|
const pubkey = '00'.repeat(32);
|
||||||
|
const mockEvent = {
|
||||||
|
kind: 10002,
|
||||||
|
pubkey: pubkey,
|
||||||
|
created_at: 1000,
|
||||||
|
tags: [
|
||||||
|
['r', 'wss://relay.example.com'],
|
||||||
|
['r', 'wss://read.example.com', 'read'],
|
||||||
|
['r', 'wss://write.example.com', 'write'],
|
||||||
|
],
|
||||||
|
content: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mock pool.list to return our event
|
||||||
|
nostrClient.pool = {
|
||||||
|
list: async () => [mockEvent],
|
||||||
|
publish: async () => {},
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = await relayManager.loadRelayList(pubkey);
|
||||||
|
assert.strictEqual(result.ok, true);
|
||||||
|
assert.strictEqual(result.source, 'event');
|
||||||
|
|
||||||
|
const entries = relayManager.getEntries();
|
||||||
|
assert.strictEqual(entries.length, 3);
|
||||||
|
|
||||||
|
const both = entries.find(e => e.url === 'wss://relay.example.com');
|
||||||
|
assert.ok(both);
|
||||||
|
assert.strictEqual(both.mode, 'both');
|
||||||
|
assert.strictEqual(both.read, true);
|
||||||
|
assert.strictEqual(both.write, true);
|
||||||
|
|
||||||
|
const read = entries.find(e => e.url === 'wss://read.example.com');
|
||||||
|
assert.ok(read);
|
||||||
|
assert.strictEqual(read.mode, 'read');
|
||||||
|
assert.strictEqual(read.read, true);
|
||||||
|
assert.strictEqual(read.write, false);
|
||||||
|
|
||||||
|
const write = entries.find(e => e.url === 'wss://write.example.com');
|
||||||
|
assert.ok(write);
|
||||||
|
assert.strictEqual(write.mode, 'write');
|
||||||
|
assert.strictEqual(write.read, false);
|
||||||
|
assert.strictEqual(write.write, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should build a valid Kind 10002 event for publishing', async () => {
|
||||||
|
const pubkey = '00'.repeat(32);
|
||||||
|
|
||||||
|
// Set up relays
|
||||||
|
relayManager.setEntries([
|
||||||
|
{ url: 'wss://relay.example.com', mode: 'both' },
|
||||||
|
{ url: 'wss://read.example.com', mode: 'read' },
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Mock signer
|
||||||
|
// Use 'local' type to bypass permission check in relayManager
|
||||||
|
const mockSigner = {
|
||||||
|
type: 'local',
|
||||||
|
signEvent: async (evt) => {
|
||||||
|
return { ...evt, id: 'mock-id', sig: 'mock-sig', pubkey };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
setActiveSigner(mockSigner);
|
||||||
|
|
||||||
|
// Mock pool.publish to capture the event
|
||||||
|
let capturedEvent = null;
|
||||||
|
nostrClient.pool = {
|
||||||
|
publish: (urls, event) => {
|
||||||
|
capturedEvent = event;
|
||||||
|
// Return a promise-like object that resolves
|
||||||
|
return {
|
||||||
|
on: (evt, cb) => { if (evt === 'ok') cb(); },
|
||||||
|
then: (cb) => { cb(); }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
await relayManager.publishRelayList(pubkey);
|
||||||
|
|
||||||
|
assert.ok(capturedEvent);
|
||||||
|
assert.strictEqual(capturedEvent.kind, 10002);
|
||||||
|
assert.strictEqual(capturedEvent.pubkey, pubkey);
|
||||||
|
|
||||||
|
// Check tags
|
||||||
|
const rTags = capturedEvent.tags.filter(t => t[0] === 'r');
|
||||||
|
assert.strictEqual(rTags.length, 2);
|
||||||
|
|
||||||
|
// Note: relayManager normalizes URLs (no trailing slash if empty path)
|
||||||
|
const bothTag = rTags.find(t => t[1] === 'wss://relay.example.com');
|
||||||
|
assert.ok(bothTag, 'Missing tag for wss://relay.example.com');
|
||||||
|
// 'both' usually has no marker or explicit? relayManager uses parseRelayTags/buildRelayListEvent logic.
|
||||||
|
// buildRelayListEvent: if mode is read -> read, write -> write, else -> no marker (both)
|
||||||
|
assert.strictEqual(bothTag.length, 2); // ['r', 'url']
|
||||||
|
|
||||||
|
const readTag = rTags.find(t => t[1] === 'wss://read.example.com');
|
||||||
|
assert.ok(readTag, 'Missing tag for wss://read.example.com');
|
||||||
|
assert.strictEqual(readTag[2], 'read');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# TODO: NIP Research Agent (2026-02-18)
|
||||||
|
|
||||||
|
- [ ] Create `tests/nostr-specs/nip65_compliance.test.mjs`
|
||||||
|
- [ ] Run `npm test -- tests/nostr-specs/nip65_compliance.test.mjs`
|
||||||
|
- [ ] Update `NIP_INVENTORY.md` (mark NIP-65 as Compliant)
|
||||||
|
- [ ] Generate `nip-report-2026-02-18.md`
|
||||||
|
- [ ] Run `npm run lint`
|
||||||
|
- [ ] Submit completion log
|
||||||
Reference in new issue
Block a user