containment 2/2: kind 10050 (inbox relays) + drafts summary in supervisor DM + grants suspended, BTCPay priority-1
ci / lint-test-leaks (pull_request) Canceled after 0s
ci / lint-test-leaks (pull_request) Canceled after 0s
- publish-10050.mjs: publishes Cayce kind 10050 (NIP-65 message-relays/ inbox) listing the 6 relays where the listener actually reads DMs. EXECUTED once with operator authorization: event id 188ef397824e8f29b5e1bea661ae65b1f8532ee97617747b9fbde57c6e8dfce9, accepted 6/6 relays. - initiative.mjs: the cycle DM to the supervisor now includes a summary of outbound_drafts from the last 24h (id, type, first 15 words) so the operator reviews what the agent WANTED to publish. - initiative.mjs: supervisor directive (CAYCE_DIRECTIVE_BTCPAY=1, reversible) injected into the cycle prompt: grants/opportunity search SUSPENDED, single priority = consolidate the BTCPay Server proposal (opportunity #106 / draft #33) ready for HUMAN sending. MANDATE text untouched (only the supervisor can change it). - initiative.mjs: add_opportunity now rejects duplicates (the agent had re-registered OpenSats ×10, HRF ×6). - opportunity #106 status -> priority-1. - check-relay-silence.mjs: queries the relays for Cayce-signed events since a timestamp; allows only kind 10050 and supervisor DMs; exits 1 on any violation. Verified: 0 events, 0 violations since deployment. - deploy.sh: sudo for the daemon restart, optional files tolerated. Gate: make check green (96 tests).
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/node
|
||||
// publish-10050 — publica el kind 10050 (NIP-65 memento: relays de inbox
|
||||
// para DMs/gift wraps) de Cayce. Autorizado explícitamente por el operador.
|
||||
// Se ejecuta UNA vez (script, no daemon).
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { SimplePool, finalizeEvent, getPublicKey } from 'nostr-tools'
|
||||
|
||||
const env = Object.fromEntries(
|
||||
readFileSync('/srv/cayce-nostr/.env', 'utf8').split('\n').filter(l => l.includes('=')).map(l => [l.slice(0, l.indexOf('=')), l.slice(l.indexOf('=') + 1)])
|
||||
)
|
||||
const skRaw = env.NSEC_HEX
|
||||
const { nsecDeserialize } = await import('nostr-tools') // soporta hex y bech32 vía fallback
|
||||
let sk
|
||||
try { sk = skRaw.startsWith('nsec1') ? nsecDeserialize(skRaw) : Buffer.from(skRaw, 'hex') } catch (e) {
|
||||
console.error('nsec ilegible:', String(e).slice(0, 80)); process.exit(1)
|
||||
}
|
||||
const pk = getPublicKey(sk)
|
||||
|
||||
// relays donde Cayce ESCUCHA DMs (los mismos del listener) — son su inbox
|
||||
const INBOX = [
|
||||
'wss://relay.damus.io',
|
||||
'wss://nos.lol',
|
||||
'wss://relay.primal.net',
|
||||
'wss://relay.snort.social',
|
||||
'wss://nostr-pub.wellorder.net',
|
||||
'wss://public.relaying.io',
|
||||
]
|
||||
const ev = finalizeEvent({
|
||||
kind: 10050,
|
||||
created_at: Math.floor(Date.now() / 1000),
|
||||
tags: INBOX.map(r => ['relay', r]),
|
||||
content: '',
|
||||
}, sk)
|
||||
console.log('[10050] pubkey:', pk)
|
||||
console.log('[10050] relays de inbox declarados:', INBOX.join(', '))
|
||||
|
||||
const pool = new SimplePool()
|
||||
const ok = []
|
||||
for (const r of INBOX) {
|
||||
try {
|
||||
await Promise.race([
|
||||
pool.publish([r], ev),
|
||||
new Promise((_, rej) => setTimeout(() => rej(new Error('timeout')), 6000)),
|
||||
])
|
||||
ok.push(r)
|
||||
} catch (e) { console.error(`[10050] ${r}: ${String(e).slice(0, 60)}`) }
|
||||
}
|
||||
pool.close(INBOX)
|
||||
console.log(`[10050] publicado/aceptado en ${ok.length}/${INBOX.length} relays — event id ${ev.id}`)
|
||||
Reference in New Issue
Block a user