NIPs in progress
llms.txt index.json Operator Manual

NIPs in progress

TresPies is a bilingual equity-data and civic firm building on the Nostr stack — a census atlas on MKStack, Spanish layers for Soapbox-family apps, an archive relay. These are the protocol gaps we keep hitting while we build, published before they're polished.

The status labels are honest: most of these are research, not drafts. Nothing here is a ratified NIP, or even a submitted one. We publish anyway because the venue works that way — NostrHub calls itself "a meritocracy you configure yourself," and the way into a meritocracy is work, in public, with receipts.

Every idea links its evidence. When one matures, we'll propose it where proposals belong — as a long-form draft on NostrHub — and this page will say so. Tell us where we're wrong: cruz@trespiesdesign.com.

NIPs en progreso

TresPies es una firma bilingüe de datos de equidad y trabajo cívico que construye sobre el stack de Nostr — un atlas del censo sobre MKStack, capas en español para las aplicaciones de la familia Soapbox, un relay de archivo. Estas son las brechas del protocolo con las que seguimos tropezando mientras construimos, publicadas antes de estar pulidas.

Las etiquetas de estado son honestas: la mayoría de esto es investigación, no borradores. Nada aquí es un NIP ratificado, ni siquiera uno presentado. Publicamos de todos modos porque así funciona este espacio — NostrHub se describe como "una meritocracia que tú mismo configuras", y a una meritocracia se entra con trabajo, en público, con evidencia.

Cada idea enlaza sus fuentes. Cuando alguna madure, la propondremos donde corresponde — como borrador de formato largo en NostrHub — y esta página lo dirá. Dinos en qué nos equivocamos: cruz@trespiesdesign.com.



Language labels clients actually use

Etiquetas de idioma que los clientes de verdad usen

DraftingOpened 2026-07-10Raw (EN) ↗Raw (ES) ↗

Nostr has no ratified way to say what language an event is written in. Soapbox's own founder tried — NIP-37 "Language Tag" closed unmerged in 2024, with the standing objection that "all automatic translation tools will already detect the language automatically anyway." A second proposal (PR #1127) is still open, still unmerged. Meanwhile the read side already shipped: NIP-50 defines a language: search filter and relay software implements it — but almost nothing on the publish side labels consistently, so there is nothing reliable to filter. Result: a Spanish-speaking user cannot dependably ask for their own language.

The gap

This is not a missing spec. NIP-32 labeling is ratified and its spec literally contains the example — ["L","ISO-639-1"], ["l","en","ISO-639-1"]. What's missing is a publish-side convention plus an adoption loop. And the auto-detection objection fails exactly where we live: short notes, code-mixed Spanish/English, and relay-level filtering that shouldn't require content analysis of every event.

What we're sketching

A thin convention document: NIP-32 language labels on kinds 1 and 30023, localized NIP-89 handler metadata so app directories aren't English-only, and a namespace caution (NIP-C0 already uses an l tag for programming language). Reference implementations, not just prose: an MKStack skill, and our es-layer forks labeling on publish. Where PR #1127 overlaps, we support it rather than compete with it.

Why us

Bilingual isn't a feature for us; it's the firm's thesis. We ship Spanish layers with symmetric EN/ES parity gates, and we hit this gap on every one of them.

Receipts

Nostr no tiene una forma ratificada de decir en qué idioma está escrito un evento. El propio fundador de Soapbox lo intentó — NIP-37 "Language Tag" se cerró sin fusionarse en 2024, con la objeción de que "las herramientas de traducción automática ya detectan el idioma de todos modos". Una segunda propuesta (PR #1127) sigue abierta, sin fusionarse. Mientras tanto, el lado de lectura ya existe: NIP-50 define un filtro de búsqueda language: y hay software de relay que lo implementa — pero casi nadie etiqueta al publicar de forma consistente, así que no hay nada confiable que filtrar. Resultado: una persona hispanohablante no puede pedir su propio idioma de manera confiable.

La brecha

No falta una especificación. NIP-32 (etiquetado) está ratificado y su propio texto contiene el ejemplo — ["L","ISO-639-1"], ["l","en","ISO-639-1"]. Lo que falta es una convención del lado de publicación y un ciclo de adopción. Y la objeción de la detección automática falla justo donde vivimos nosotros: notas cortas, texto mezclado español/inglés, y filtrado a nivel de relay que no debería exigir analizar el contenido de cada evento.

Lo que estamos esbozando

Un documento de convención delgado: etiquetas de idioma NIP-32 en los kinds 1 y 30023, metadatos NIP-89 localizados para que los directorios de aplicaciones no existan solo en inglés, y una advertencia de espacios de nombres (NIP-C0 ya usa una etiqueta l para lenguaje de programación). Implementaciones de referencia, no solo prosa: un skill de MKStack, y nuestras capas en español etiquetando al publicar. Donde PR #1127 coincida, lo apoyamos en lugar de competir.

Por qué nosotros

Para nosotros lo bilingüe no es una función; es la tesis de la firma. Publicamos capas en español con verificaciones simétricas de paridad EN/ES, y chocamos con esta brecha en cada una.

Evidencia


Push delivery, revived

Notificaciones push, retomadas

ResearchingOpened 2026-07-10Raw (EN) ↗Raw (ES) ↗

No NIP covers push notifications. We scanned the full NIP index — nothing numbered, lettered, or hex-coded addresses how an event reaches a phone that isn't looking. The one serious attempt, Amethyst's "Event Watcher API" (PR #1528), had already run in production for about a year before it was even proposed — and it still closed unmerged in 2025, with the author's own note that Pokey's success made him question whether the idea was worth pursuing. The gap didn't close; the person carrying it put it down.

Why it matters more than it looks

Apple's Lockdown Mode blocks Service Workers entirely, so PWA web-push isn't degraded there — it's absent. The users who opt into the highest security get the least notification capability, and every consumer Nostr app re-solves this privately or ships without it.

What we're sketching

Study before proposing: PR #1528's design and Pokey's working model first. The likely shape is a slim registration spec with wrapped delivery — the push server should never learn which pubkey you watch. But the first deliverable is practical, not protocol: an MKStack skill that standardizes the non-protocol fallback (native push via Capacitor/APNs/FCM, web-push where it exists, honest Lockdown Mode behavior) so scaffolded apps stop re-solving it one at a time. A fallback pattern people actually ship beats a spec nobody implements.

Why us

We're building bilingual consumer surfaces on this stack, and civic information is time-sensitive — a deadline notice that arrives late is a notice that didn't arrive.

Receipts

Ningún NIP cubre las notificaciones push. Revisamos el índice completo de NIPs — nada, con número, letra o código hex, define cómo un evento llega a un teléfono que no está mirando. El único intento serio, el "Event Watcher API" de Amethyst (PR #1528), ya llevaba cerca de un año funcionando en producción antes de proponerse — y aun así se cerró sin fusionarse en 2025, con una nota del propio autor diciendo que el éxito de Pokey lo hizo dudar de si valía la pena seguir. La brecha no se cerró; la persona que la cargaba la soltó.

Por qué importa más de lo que parece

El Lockdown Mode de Apple bloquea los Service Workers por completo, así que el push web de una PWA ahí no se degrada — desaparece. Las personas que eligen la máxima seguridad reciben la menor capacidad de notificación, y cada aplicación de consumo en Nostr resuelve esto en privado o publica sin resolverlo.

Lo que estamos esbozando

Estudiar antes de proponer: primero el diseño de PR #1528 y el modelo de Pokey. La forma probable es una especificación delgada de registro con entrega envuelta — el servidor de push nunca debería saber qué pubkey observas. Pero el primer entregable es práctico, no de protocolo: un skill de MKStack que estandarice la alternativa fuera del protocolo (push nativo vía Capacitor/APNs/FCM, push web donde exista, comportamiento honesto bajo Lockdown Mode) para que las aplicaciones dejen de resolverlo una por una. Un patrón que la gente de verdad publica vale más que una especificación que nadie implementa.

Por qué nosotros

Construimos superficies de consumo bilingües sobre este stack, y la información cívica es sensible al tiempo — un aviso de plazo que llega tarde es un aviso que no llegó.

Evidencia


Stop wiping profiles: merge semantics for replaceable events

Dejar de borrar perfiles: semántica de fusión para eventos reemplazables

ResearchingOpened 2026-07-10Raw (EN) ↗Raw (ES) ↗

Profiles (kind 0) and contact lists (kind 3) are replaceable events: last write wins, whole event. A client that publishes its own partial view of a profile silently erases every field it doesn't understand — for everyone, everywhere. The protocol's own tracker has documented this since 2023 (issue #261), and it bites real users: Damus's "Balaji's bug" was a profile wiped by exactly this mechanism. Relays can't fix it — for each pubkey and kind, only the latest event is stored. Only clients can.

The gap

There is no stated rule that a client publishing a replaceable event should first merge against the latest known state and preserve fields it doesn't recognize. Every client that gets this right does so by folklore; every new client gets a chance to wipe your lightning address.

What we're sketching

A small SHOULD: before publishing a replaceable kind, fetch the latest known event, deep-merge your changes into it, and preserve unknown fields verbatim. Alongside the prose, the part we think matters more: a conformance fixture set — event pairs where a correct merge has one right answer — and a reference implementation as an MKStack skill/hook, so scaffolded apps get safe publishing without reading a spec. Open question we're researching: whether unknown-field preservation can be specified tightly enough to test without freezing legitimate field deletion.

Why us

We're shipping apps on the scaffold this failure class lives in, and "your app quietly destroyed my profile" is the kind of trust failure a civic tool can't survive.

Receipts

Los perfiles (kind 0) y las listas de contactos (kind 3) son eventos reemplazables: gana la última escritura, el evento completo. Un cliente que publica su vista parcial de un perfil borra en silencio cada campo que no entiende — para todos, en todas partes. El propio rastreador del protocolo lo documenta desde 2023 (issue #261), y afecta a usuarios reales: el "bug de Balaji" en Damus fue un perfil borrado exactamente por este mecanismo. Los relays no pueden arreglarlo — por cada pubkey y kind solo se guarda el evento más reciente. Solo los clientes pueden.

La brecha

No existe una regla que diga que un cliente, antes de publicar un evento reemplazable, debería fusionar contra el último estado conocido y preservar los campos que no reconoce. Cada cliente que lo hace bien lo hace por tradición oral; cada cliente nuevo tiene su oportunidad de borrar tu dirección de lightning.

Lo que estamos esbozando

Un SHOULD pequeño: antes de publicar un kind reemplazable, obtener el último evento conocido, fusionar los cambios sobre él, y preservar los campos desconocidos tal cual. Junto a la prosa, la parte que creemos que importa más: un conjunto de casos de conformidad — pares de eventos donde una fusión correcta tiene una sola respuesta válida — y una implementación de referencia como skill/hook de MKStack, para que las aplicaciones generadas publiquen de forma segura sin leer una especificación. Pregunta abierta que investigamos: si la preservación de campos desconocidos puede especificarse con suficiente precisión para probarse sin congelar el borrado legítimo de campos.

Por qué nosotros

Publicamos aplicaciones sobre el mismo andamiaje donde vive esta clase de falla, y "tu aplicación destruyó mi perfil en silencio" es el tipo de falla de confianza que una herramienta cívica no sobrevive.

Evidencia


Relays that say what they keep

Relays que digan qué guardan

ExploringOpened 2026-07-10Raw (EN) ↗Raw (ES) ↗

Not one relay or media host we could find publishes a contractual durability promise — free or paid. The measured economics explain why: 95% of free relays can't cover operating costs from zap income, and 64% receive zero zaps at all (Wei & Tyson, CoNEXT '25). Users treat relays as storage; the economics say they're caches. NIP-11 lets a relay describe its operational limits, and NIP-66 monitors whether a relay is alive — but there is no standard, machine-readable way for a relay to declare how long it keeps events, and nothing that checks such a declaration against observed behavior.

The gap

Durability on Nostr is currently a vibe. A user picking write relays, or an organization with records-retention obligations, has no signal to select on — liveness isn't retention, and payment isn't a promise.

What we're sketching

Three pieces that only work together: a machine-readable retention declaration (a NIP-11 extension or companion event), NIP-66-class monitors that verify claims longitudinally — "promised 30 days; observed 90" — so declarations earn reputations, and client UX that surfaces it at relay-selection time. Declared retention that nobody verifies is marketing; verified retention is infrastructure.

Why us

We run the archive-relay pattern ourselves (own strfry as source of truth, public relays as reach), and we build for civic organizations that answer to actual records-retention rules.

Receipts

Ningún relay ni servidor de medios que pudimos encontrar publica una promesa contractual de durabilidad — gratuito o de pago. La economía medida explica por qué: el 95% de los relays gratuitos no cubre sus costos operativos con ingresos por zaps, y el 64% no recibe ningún zap (Wei & Tyson, CoNEXT '25). La gente trata los relays como almacenamiento; la economía dice que son cachés. NIP-11 permite que un relay describa sus límites operativos, y NIP-66 monitorea si un relay está vivo — pero no existe una forma estándar y legible por máquina de que un relay declare cuánto tiempo guarda los eventos, ni nada que compare esa declaración con el comportamiento observado.

La brecha

Hoy la durabilidad en Nostr es una sensación. Una persona eligiendo sus relays de escritura, o una organización con obligaciones de retención de registros, no tiene ninguna señal sobre la cual decidir — estar vivo no es retener, y cobrar no es prometer.

Lo que estamos esbozando

Tres piezas que solo funcionan juntas: una declaración de retención legible por máquina (una extensión de NIP-11 o un evento compañero), monitores tipo NIP-66 que verifiquen las declaraciones a lo largo del tiempo — "prometió 30 días; se observaron 90" — para que las declaraciones ganen reputación, y una interfaz de cliente que lo muestre al momento de elegir relays. Una retención declarada que nadie verifica es publicidad; una retención verificada es infraestructura.

Por qué nosotros

Nosotros mismos operamos el patrón de relay de archivo (strfry propio como fuente de verdad, relays públicos como alcance), y construimos para organizaciones cívicas que responden a reglas reales de retención de registros.

Evidencia


Public datasets on open rails

Datos públicos sobre rieles abiertos

ExploringOpened 2026-07-10Raw (EN) ↗Raw (ES) ↗

Public-interest data — census extracts, language-access data, eviction filings — lives on servers that get defunded, redesigned, or quietly taken down. Nostr already over-replicates social events (the average post lands on 34.6 relays, measured), but it has no convention for announcing a dataset: what it is, where it came from, which vintage, what license, where the mirrors are. Before building a census atlas on this stack we looked for a precedent; none exists.

The gap

NIP-94 describes a file. A dataset needs more: source authority, vintage (ACS 2019–2023 is not ACS 2020–2024), geographic coverage, license, content hash, and a mirror list a client can actually resolve. Without that, "the data is decentralized" is a slogan — you can't verify what a dashboard is built on, and you can't re-host what you can't identify.

What we're sketching

A NIP-94-family announcement for datasets: source, vintage, geography, license, sha256, mirror list (Blossom BUD-04 mirroring makes the copies real). The consumer story: a civic dashboard cites the announcement event, anyone verifies the hash, anyone re-hosts the blob, and the dashboard survives its original host. We're dogfooding the substrate now — a bilingual census atlas served entirely from static tiles — and the announcement convention is the missing provenance layer under it.

Why us

Equity data for overlooked communities is our practice. The communities most likely to need this data are the least served by the infrastructure that currently holds it.

Receipts

Los datos de interés público — extractos del censo, datos de acceso lingüístico, registros de desalojos — viven en servidores que pierden fondos, se rediseñan o se retiran sin aviso. Nostr ya sobre-replica los eventos sociales (una publicación promedio llega a 34.6 relays, medido), pero no tiene una convención para anunciar un conjunto de datos: qué es, de dónde viene, de qué vendimia, con qué licencia, dónde están los espejos. Antes de construir un atlas del censo sobre este stack buscamos un precedente; no existe.

La brecha

NIP-94 describe un archivo. Un conjunto de datos necesita más: autoridad de origen, vendimia (ACS 2019–2023 no es ACS 2020–2024), cobertura geográfica, licencia, hash del contenido, y una lista de espejos que un cliente pueda resolver. Sin eso, "los datos son descentralizados" es un eslogan — no puedes verificar sobre qué está construido un tablero, y no puedes re-hospedar lo que no puedes identificar.

Lo que estamos esbozando

Un anuncio de la familia NIP-94 para conjuntos de datos: origen, vendimia, geografía, licencia, sha256, lista de espejos (el espejado BUD-04 de Blossom hace que las copias sean reales). La historia del consumidor: un tablero cívico cita el evento de anuncio, cualquiera verifica el hash, cualquiera re-hospeda el blob, y el tablero sobrevive a su servidor original. Ya estamos probando el sustrato — un atlas del censo bilingüe servido enteramente desde teselas estáticas — y la convención de anuncio es la capa de procedencia que le falta debajo.

Por qué nosotros

Los datos de equidad para comunidades pasadas por alto son nuestra práctica. Las comunidades que más van a necesitar estos datos son las peor servidas por la infraestructura que hoy los guarda.

Evidencia


Watching, not carrying

Gaps we track without presuming to lead them. Listed so you know we know.

Observando, sin cargar

Brechas que seguimos sin pretender liderarlas. Las listamos para que sepas que las conocemos.


Contact and provenance

Write to cruz@trespiesdesign.com. An npub with NIP-05 verification on this domain ships with our first git-anchored repo — we're setting up key custody deliberately, not quickly, for the reasons this page keeps citing.

Everything above is grounded in the Soapbox Stack Operator Manual we maintain on this same domain — 16 chapters, live-verified citations, raw markdown and an llms.txt for agents. The raw markdown for this page is indexed at /NIPs/llms.txt, same convention.

Contacto y procedencia

Escríbenos a cruz@trespiesdesign.com. Un npub con verificación NIP-05 en este dominio llegará con nuestro primer repositorio anclado en git — estamos configurando la custodia de claves con calma deliberada, no con prisa, por las mismas razones que esta página cita una y otra vez.

Todo lo anterior está fundamentado en el Manual del operador del stack Soapbox que mantenemos en este mismo dominio — 16 capítulos, citas verificadas en vivo, markdown crudo y un llms.txt para agentes. El markdown crudo de esta página está indexado en /NIPs/llms.txt, misma convención.