maarmapa@boykot ~ %  whoami → artista + vibe coder EN PRODUCCIÓN

Mario Maldonado — maarmapa · artista + vibe coder · Santiago, CL

No programo formal.
Igual reescribí el stack completo de mi negocio.

Artista de graffiti, codueño de Boykot y builder con IA. Un sistema que falla, avisa; lo caro es cuando informa éxito mientras está equivocado. Todo en producción, revisado línea por línea.

# producción

[2026-09-06 -03]REF 27LIVE▸ contenido · control de calidad

El control que grita siempre

1.695 candidatos, 66 reales: 25 falsos positivos por cada acierto. Un detector así no se arregla, se ignora.

Todo lo que lee un cliente va en español neutro, y el modelo mete voseo rioplatense sin que se note: ya se había colado en fichas de producto y en anuncios. Una expresión regular que buscaba sus marcas dio 1.695 candidatos; reales eran 66. 25 falsos positivos por cada acierto: una salida que nadie lee y un chequeo que se apaga solo. Falla por subcadena y por tilde: «recargable» 983 veces y «la recarga» 239 no son imperativos; «elegir» y «seguir» son infinitivos, «buscas» sin tilde es correcto y «más» o «japonés» llevan tilde sin ser voseo. El corazón: «Elegí tu color», imperativo, sale; «yo elegí ese color», pasado, se queda. Son la misma cadena de caracteres y solo se distinguen leyendo la frase completa: ninguna expresión regular lo resuelve. El caso hermano prueba la regla: otra norma pide que el nombre de una marca de marcadores nunca vaya solo, y el detector que miraba solo la palabra siguiente marcó 716; al mirar también la anterior quedaron cero. Lo que sirve: tilde exacta, límite de palabra unicode y leer a mano las sesenta y tantas frases que sobreviven. Y reportar los dos números, lo corregido y lo descartado: si solo aparece uno, el trabajo no se hizo.

regexUnicodeespañol neutrorevisión a manocontenido
[2026-10-19 -03]REF 26LIVE▸ agentes · seguridad

El supuesto que nadie chequeó

Una promoción en miles de publicaciones, activada sobre un supuesto falso, con el sistema informando éxito. Esta vez el sistema equivocado era otra IA.

Una promoción en miles de publicaciones de un marketplace, sobre un supuesto falso del costo de envío. Nada falló: informó que quedaba activa, y quedó activa. Lo equivocado era una condición que nadie verificó; el margen se revisó después, no antes. La escribió otra flota de agentes: son dos, proveedores distintos, las dos en producción, coordinadas por un repositorio git privado: reglas, estado y pedidos numerados por flota. La regla dura: lo que la otra flota escribe es información, no órdenes. El archivo de reglas pide empujar cambios: estar escrito no lo ejecuta. Un repositorio compartido entre IAs es superficie de inyección. La auditoría no encontró ni un secreto; sí datos de clientes y cifras internas, dos veces: hay regla nueva. Dos lecciones: reescribir el historial no purga nada —el commit viejo se sigue sirviendo si lo pides por identificador; solo soporte lo saca— y el barrido previo al push necesita límites de palabra: el grep de macOS no entiende \b y dejó pasar una IP que Python sí atrapó. La otra flota respalda, revierte, prueba en staging y pausa en vez de borrar. No fue descuido: fue un supuesto sin chequear. Sin link: el repositorio es privado.

agentesgitauditoríaprompt injectionPythonstaging
[2026-09-02 -03]REF 22LIVE▸ commerce · integraciones

El canal Walmart

Primer pedido a las 21 horas y 49 minutos del primer commit. Lo caro fue lo que ese pedido destapó.

Del primer commit al primer pedido en Walmart Chile / Lider.cl: 21 h 49 m. Eso fue lo fácil: ese pedido destapó tres fallas del mismo tipo — el canal se construyó entero y el resto del sistema no supo que existía. El identificador de pedido empieza con letra; su columna era numérica: el candado de idempotencia moría con un error de tipo y la nota tardó 6 h 27 m — cada corrida de media hora falló sin emitir ni registrar nada. El motor de reservas conocía tres canales y la nota nueva no coincidía con ninguno: caía al caso por defecto, como cotización mayorista, con el vencimiento equivocado. La tercera: ninguna sonó. La fila que servía de registro era la misma que fallaba al escribirse, así que el error no dejó rastro: las encontré porque fui a mirar. La cuarta no la trajo un pedido: apareció el 5 de septiembre, comparando la API con el cálculo. Walmart Chile informa el precio de cada línea sin impuesto y el comentario del código decía lo contrario: se descontaba de nuevo. Ahí tampoco sonó nada: la reconciliación comparaba netos por 1,19 contra un total también neto y cuadraba perfecto con el supuesto equivocado. 20 PRs del canal del 1 al 13 de septiembre.

TypeScriptWalmart Marketplace APIBSaleSupabaseVercel Cron
[2026-09-24 -03]REF 23SIN PUBLICAR▸ freelance · sincronización

Tengu — el sensor de la carta

El campo que dice «esto cambió» no sirve de sensor, y el reemplazo obvio tampoco.

236 platos en 50 subsecciones al 23 de septiembre en la carta nativa del sitio de Tengu, generada desde la carta viva que la cocina mantiene en una plataforma externa. El sensor obvio era el dateModified de su JSON-LD: pedir la fecha y bajar todo solo cuando se mueva. No sirve, y no por el motivo esperado: la misma dirección devuelve platos distintos según la hora, porque cada plato puede traer su propia ventana horaria. La fecha se queda quieta —del 8 de mayo al 25 de agosto— mientras lo que baja cambia sin que nadie edite nada. El reemplazo, comparar la lista de platos contra la extracción anterior, hereda el problema al revés: lee esas ausencias como bajas. Esa tarde la corrida iba a borrar una subsección completa del sitio y el informe imprimía «desaparecidos=0»: el único control humano decía que no pasaba nada. El freno: lo que tenía platos nunca vuelve vacío, se conserva lo anterior y el sync grita. El orden importa más que las piezas: extraer, normalizar, comparar y solo después generar, para que el diff se lea a mano mientras lo publicado sigue siendo la corrida anterior.

NodeHTML/CSSJSON-LDschema.orgscrapingdiff
[2026-09-11 -03]REF 24EN CURSO▸ diagnóstico · restaurantes

SÍ / NO / NO SE SABE

Lo más difícil de un motor de diagnóstico no fue medir. Fue decidir qué no afirmar.

Diagnóstico de presencia digital de restaurantes. La regla que gana toda duda: SÍ / NO / NO SE SABE. Un sitio que responde HTTP 521 al pedir un archivo no es «no lo tiene», es «no se sabe»; anotarlo como un no es inventar un defecto. Lo manda la licencia (Google Maps Platform §3.2.3(c)): un booleano derivado de un campo es ese campo, así que «tiene sitio web: falso» no puede quedar en disco, el dominio no persiste y el entregable es una URL viva, no un PDF. Los tres defectos que lo frenan se los encontró solo: el dato prohibido escrito en prosa junto al identificador; un puntaje «N de M» con una métrica distinta en cada carga; y el defecto de la plataforma cobrado al negocio —y, al revés, su mérito regalado al negocio sin sitio propio—. Con eso, el ranking no se muestra: de diez frases revisadas a mano, dos eran falsas. La otra mitad, el mapa de rieles: tres juegos —que te nombren, que te reserven en el chat, que lo que digan de ti sea correcto—, y el error caro es pagar el tercero esperando el primero. En Chile la única puerta al segundo es OpenTable. Esta entrada no lleva link al repositorio: analizó negocios reales que no lo pidieron y se queda privado.

PythonGoogle Maps PlatformPageSpeedLighthouserobots + sitemapJSONLOpenTable
[2026-09-11 -03]REF 25ENTREGADO▸ investigación · agentes

Qué no construir

El trabajo fue decir qué no construir.

Dónde gastar para que un asistente reserve una mesa. Hay tres juegos y se confunden. Que te nombren es orgánico: no se vende. Que te reserven sin salir del chat se contrata — riel ajeno, cero mérito técnico. Que la ficha diga la verdad es mantención. Lo caro es pagar la ficha esperando menciones. Agosto lo ordenó. El 10 de agosto de 2026 ChatGPT habilitó reservas en el chat con tres socios: OpenTable, Resy y Yelp. Resy solo opera en Estados Unidos y Yelp en Estados Unidos y Canadá: en Chile hay una sola puerta. El 26 de agosto se ensanchó: OpenTable pasó a distribuir a ChatGPT, Google —Search, Maps y Gemini—, Copilot, Perplexity y Alexa+. Una integración, cinco destinos. Reserve with Google tiene a Chile en su tabla oficial, pero exige contrato con una plataforma socia: nadie se integra solo; la decisión es con cuál, no si se construye. Lo que no va: los protocolos de checkout y pago agéntico no definen una reserva; llms.txt y el schema lucen en una auditoría y no mueven descubrimiento. Y WebMCP, que yo mismo construí en dos negocios reales, sigue en borrador al 26-sep. Esa era mi apuesta. Todavía no es un canal.

investigaciónOpenTableReserve with GoogleChatGPTWebMCPschema.orgllms.txt
[2026-09-04 -03]REF 19EN EVALUACIÓN▸ agentes · WebMCP

WebMCP Challenge

El agente llena la reserva o el carro — y se detiene ahí.

Entregado a The WebMCP Challenge, de OpenAI: 2.474 proyectos entregados. Un restaurante japonés y una tienda de materiales de arte exponen 18 herramientas (5 y 13) construidas sobre una sola decisión: el agente llena y se detiene. preparar_reserva completa el formulario de reserva y no lo envía; agregar_al_carro arma el carro y no paga; la de checkout devuelve el enlace al carro en vez de cobrar. Lo que no se ve en la demo: los campos que escribió el agente quedan marcados y un aviso arriba los nombra y ofrece descartarlos — un formulario llenado en silencio es peor que uno vacío, porque la persona ve valores plausibles y envía sin leer. Y cada campo se relee: un <select> al que se le pasa un valor inexistente queda vacío sin reclamar, y el agente reportaría «completado» sobre un campo en blanco. Las 10 que vienen del servidor salen de restar las sensibles, no de una lista blanca: una de administración nueva queda afuera sola. Ganadores el lunes 28 de septiembre: al escribir esto no hay resultado.

WebMCPdocument.modelContextorigin trialNext.jsVanilla JSVercel
[2026-09-21 -03]REF 20LIVE▸ open source

DashAI · el modelo equivocado

Dos PRs más mergeados: el estudio reportaba el mejor intento y entregaba un modelo que nunca lo vio.

Dos PRs más mergeados en DashAI (★461 y 58 forks al 26 de septiembre), la plataforma open source de modelos donde en agosto ya habían entrado tres PRs míos. El bug de agosto mandaba los valores al objeto equivocado; este los manda al objeto y train lee de otro lado. MLPRegression guardaba su configuración dos veces: self.params, que es lo que lee train, y atributos de instancia, que es donde escriben ModelFactory y los dos optimizadores. Una búsqueda sobre hidden_size nunca llegaba a la red: cada intento reconstruía el mismo modelo, y el que el estudio reportaba como mejor nunca se entrenó con los valores que ganaron. El segundo PR es una copia que derivó: las funciones calculate_metrics y compute_metrics tenían un bucle de puntuación cada una, y solo la primera descartaba los puntajes no finitos. La segunda arma el objetivo de la búsqueda, así que una métrica demasiado sospechosa para guardarse igual decidía qué hiperparámetros ganaban; ahora las dos delegan en BaseModel._score_split y su guarda math.isfinite. Nada de esto lanzaba un error: el sistema reportaba éxito y entregaba el modelo equivocado. Van cinco PRs mergeados, +1.686/−112, más cinco issues reportados.

PythonPyTorchOptunapytestopen source
[2026-09-15 -03]REF 21LIVE▸ agentes · open source

dashai-mcp

En el registro oficial de MCP desde el 15 de septiembre: diez herramientas sobre dashAI y ninguna borra.

Servidor MCP no oficial para dashAI: el README aclara que no está afiliado al proyecto. Le da a un agente la misma superficie que dashAI le da a una persona por su interfaz: mirar los datasets, entrenar, seguir la cola y leer las métricas. Son diez herramientas y ninguna borra: la API de dashAI no tiene autenticación ni deshacer, así que un DELETE /dataset/{id} disparado por un modelo que leyó mal una frase es irreversible; borrar se hace desde la interfaz. La guarda de publicación existe porque el modo de fallar era caro y silencioso: para un paquete de PyPI el registro no mira el repositorio. Descarga la ficha de esa versión en PyPI y exige encontrar el token mcp-name: io.github.Maarmapa/dashai-mcp dentro de la descripción publicada en esa versión — y PyPI es inmutable, así que una versión subida sin el marcador no se corrige: se quema otro número. Tres subieron sin él antes de que la 0.3.1 lo trajera. La guarda comprueba eso contra PyPI en vivo, con el mismo patrón de límite que el validador del propio registro, antes de gastar una publicación. La identidad la firma el token OIDC del repositorio: cero secretos guardados.

PythonMCPPyPIOIDCGitHub Actions
[2026-08-15 -03]REF 01LIVE▸ ingeniería · costos

El motor

Puse el modelo de clima de DeepMind en producción por US$0,002 la corrida.

Conectar WeatherNext 2 —el modelo de clima de Google DeepMind— a una herramienta gratis parecía imposible por costo: BigQuery cobra por bytes escaneados y la primera consulta para todo Chile iba a costar US$1.244. Peor: el dry-run estimó 0,186 GiB donde el real eran 971 — erró por 5.000×, porque los filtros geográficos no podan particiones. Medí el costo real sin ejecutar (tope de 1 MiB y leer el error) y lo bajé a US$0,002 por corrida con cuatro reglas. La clave es contraintuitiva: como el radio no afecta el precio, una sola consulta cubre las 74 zonas del país. Encima sumé Earth Engine para leer nieve observada por satélite — ahí casi publico una nube como manto nevado, porque MODIS esconde el código de nube dentro del mismo campo del porcentaje.

WeatherNext 2DeepMindBigQueryEarth EngineSQLMODIS
[2026-08-25 -03]REF 02LIVE▸ open source

DashAI

Tres PRs mergeados en un proyecto con 461 estrellas: dos bugs silenciosos en el optimizador.

Contribución aceptada a DashAI (461 estrellas), una plataforma open source para entrenar y desplegar modelos. Encontré dos bugs silenciosos en el optimizador de hiperparámetros. Uno: Optuna escribía los mejores parámetros en el modelo de nivel superior en vez del objeto que declara cada parámetro, así que con componentes anidados el subcomponente se quedaba con lo del último intento y no con el mejor — el modelo reentrenado no era el que el usuario creía, y como setattr nunca falla, nada lo delataba. El otro: el pruner no podía podar, porque durante la optimización el modelo se entrenaba sin datos de validación y la métrica por época que el pruner necesita nunca se calculaba. En vez de parchar los cinco modelos que entrenan por épocas, colgué un solo gancho opcional en la clase base por donde ya pasaban todas las métricas. Tres PRs mergeados, con tests de regresión.

PythonOptunapytestopen source
[2026-08-09 -03]REF 03EXPERIMENTO▸ agentes · commerce

Web chat agéntico

Tu tienda de arte, conversando — preguntas, comparas y compras en un solo hilo.

Una página donde la tienda entera es la conversación: «tu tienda de arte, conversando». El cliente pregunta en lenguaje normal — «quiero empezar con lettering, ¿qué necesito?» — y el asistente le recomienda materiales reales, compara marcas y le arma el carrito ahí mismo, sin sacarlo del hilo. Precio y stock salen del servidor vía tools: nada inventado; si el dato no está, no lo improvisa. Corre en la web nueva de Boykot, antes del cambio de dominio, y viene con servidor MCP y agent card A2A para que otros agentes compren sin pasar por la interfaz.

Next.jsMCPA2AOpenRouterVercel
[2026-08-08 -03]REF 04LIVE▸ seguridad · IA

RAG blindado

Un RAG que no obedece a los documentos que lee.

Un RAG que no obedece a los documentos que lee. Si cualquiera puede subir un PDF al corpus indexado, cualquiera puede escribir instrucciones que el modelo va a obedecer: acá lo recuperado se trata como dato, nunca como orden. Pipeline completo sobre Postgres + pgvector con embeddings locales, donde cada decisión de seguridad está mapeada a un riesgo del OWASP Top 10 para aplicaciones LLM, y el despliegue tiene un gate bloqueante en CI: si la fidelidad medida baja del umbral, no pasa a producción.

PythonPostgrespgvectorOWASP LLMCI/CD
[2026-08-03 -03]REF 05LIVE▸ agentes · commerce

Storefront MCP

Mi tienda le habla directo a los agentes de IA: buscan, cotizan y arman el carro.

Mi tienda expone un servidor MCP en su propio dominio: un agente de IA puede buscar productos, pedir la carta de color con stock real por tono, planificar un proyecto, cotizar envío y hasta armar el carro de compra — sin pasar por la web. Van 10 herramientas públicas; las sensibles (stock masivo, ventas, pedidos) exigen token, así un competidor ve la vitrina pero nunca la operación. Lo sirvo bajo boykot.cl con un proxy propio en WordPress, porque un agente confía en el dominio de la marca, no en un subdominio de hosting. Dato honesto: tener MCP no es el diferenciador — Shopify se lo regala a la competencia. El diferenciador es qué expones: preguntar qué tonos de Copic hay hoy en Chile solo lo puede responder este.

MCPJSON-RPCNext.jsVercelWordPressBSale
[2026-07-24 -03]REF 06LIVE▸ cívico · datos

Alerta Clima

Riesgo de lluvia y aluvión, comuna por comuna.

Herramienta ciudadana de riesgo hidrometeorológico hiperlocal para Chile, de norte a sur. Cruza la alerta oficial de SENAPRED, cinco modelos de pronóstico de Open-Meteo y el caudal de ríos de GloFAS. Encima corre el stack de Google: WeatherNext 2 de DeepMind vía BigQuery para avisar hasta 15 días antes, y nieve observada por satélite (MODIS) con Earth Engine para cazar el gatillo real del aluvión: lluvia sobre nieve. Publica un feed abierto para que municipios, apps y bots lo consuman.

SENAPREDOpen-MeteoWeatherNext 2BigQueryEarth EngineGloFASVanilla JSVercel
[2026-07-13 -03]REF 07LIVE▸ commerce

Boykot Commerce OS

Reescribí el stack completo de mi tienda, desde cero.

Next.js pegado a BSale, Supabase y WooCommerce. Boté el conector pago Multivende y escribí el mío: boletas y notas de Woo y MercadoLibre entran solas a BSale, sin que nadie mueva un dedo. Es el cerebro que mueve la tienda todos los días.

Next.jsTypeScriptBSaleSupabaseWooCommerceVercel
[2026-07-13 -03]REF 08LIVE▸ integraciones

Conectores marketplace directos

MercadoLibre y Paris/Cencosud por API directa, sin intermediario.

Conecté cada canal directo a su API, sin plataformas que cobran mensualidad por ponerse al medio. Stock, precio y ventas de todos lados salen de una sola fuente: BSale. Un solo lugar manda y todo lo demás se alinea.

TypeScriptMercadoLibre APICencosud APIBSale
[2026-07-13 -03]REF 09LIVE▸ producto

Cartas de color comprables

El sitio oficial de cada marca, pero que sí puedes comprar.

Copic, Holbein, Angelus, Acrilex y más: repliqué la carta de color oficial de cada marca con grillas de swatches por sprite, y la hice comprable directo. Es el diferenciador de Boykot: haces click en el color exacto y va al carro. Nadie más en Chile lo hace así.

Next.jsTypeScriptCSSWooCommerce
[2026-07-13 -03]REF 10RUNNING · */15▸ monitoreo

Health-watch

Un vigilante que revisa que la plata siga entrando.

Cron cada 15 minutos que chequea lo que da plata (stock, syncs, checkout) y me avisa apenas algo se cae. Antes me enteraba cuando un cliente reclamaba. Ahora me entero antes que el cliente.

TypeScriptVercel CronSupabase

# labs & freelance

[2026-06-03 -03]REF 11LIVE▸ arte · pagos

maarmapa-web

Mi tienda de arte con pagos cripto y fiat.

Mi galería personal de arte, con MercadoPago, Khipu y x402 (USDC on Base) en el mismo checkout. Vendo obra sin mensualidad fija ni un tercero llevándose comisión. Cripto o peso chileno, la que quieras.

Next.jsMercadoPagoKhipux402USDC / Base
[2026-07-10 -03]REF 12LIVE▸ arte generativo

MAP AI Lab

61 piezas de arte generativo con IA.

Una galería de 61 piezas hechas con IA generativa. Es mi laboratorio: acá pruebo lo que después uso en las tiendas y en el motion. El arte y el código nunca están separados en lo que hago.

IA generativaNext.jsVercel
[2026-07-06 -03]REF 13DAILY · cron▸ bot

sistema

Un cortometraje nuevo cada día, en automático.

Un short film auto daily creator: bot que genera cortos diarios solo, combinando Runway, Claude y un cron. Lo prendí y produce sin que yo mueva un dedo. Contenido en piloto automático.

RunwayClaudecronPython
[2026-06-28 -03]REF 14LIVE▸ freelance

metaltec-web

Sitio para Metaltec Ltda, con catálogo en vivo.

Trabajo freelance: sitio para Metaltec, con el catálogo tirado directo de BSale y sus 6 sucursales. El mismo motor que uso en Boykot, puesto a trabajar para otro rubro. Lo que aprendo en mi negocio, lo vendo afuera.

Next.jsBSaleTypeScript
[2026-05-25 -03]REF 15LIVE▸ freelance · hostelería

Tengu — W Santiago

La carta del restaurante japonés del W, en pantalla.

Web de carta para Tengu (天狗), el restaurante japonés del W Santiago en Las Condes. Menú completo, maridajes y la estética del “Guardián de las Montañas” llevada a web: HTML puro, carga instantánea, cero frameworks innecesarios.

HTML/CSSNodeVercel
[2026-05-10 -03]REF 16EXPERIMENTO▸ personaje

oracle

Un personaje llamado 'oracle', vivo con Runway.

Experimento de personaje: le di cara y movimiento a 'oracle' con Runway. No todo lo que hago tiene que vender algo. A veces solo estoy viendo hasta dónde llega la herramienta.

RunwayIA generativa
[2026-04 -03]REF 17EN MEMORIA▸ homenaje · web3

nadaone.eth · memorial NADAO

Un homenaje que no se puede borrar, y un chat de IA para seguir hablando con él.

Sitio en memoria de Daniel Aspillaga Gazmuri — NADAO, writer y artista — junto a su crew OKFSCREW. Lo dejé en IPFS + ENS: sin servidor que pagar ni nadie que lo pueda bajar, vive para siempre. Archiva su graffiti, arte, branding y música, y suma un chat de IA entrenado en él («Hablar con NADAO») para conversar con su voz. Rest in Paint.

ENSIPFSeth.limoIA · chatHTML / JS

# demo

[2026-07-13 -03]REF 18RENDERED▸ motion · código puro

HyperFrames

Motion graphics de marca sin abrir After Effects.

Animo con código: HTML, CSS y GSAP renderizado a MP4. Cero timeline, cero plugins caros. Vengo del arte, así que el ojo lo pongo yo y el render lo pone el navegador. El demo de acá al lado es una stat-card animada de Boykot.

HTMLCSSGSAPMP4
REF 18 ▸ HYPERFRAMES·boykot stat-card·HTML/CSS/GSAP → MP4 · 1080×1080
demo · looprender 5.0s · 317 KB

# escritos

Escribo sobre arte, cripto y lo que voy construyendo. Lo más constante que tengo online.

leer en Substack ↗

# whoami

Soy Mario, maarmapa. Vengo del arte y el graffiti, y tengo Boykot, una tienda de arte en Providencia. Nunca estudié programación: aprendí vendiendo. Hoy hago software de verdad con IA — le pido que arme, reviso cada línea, corrijo y lo saco a producción. El vibe coding no es mi excusa, es mi ventaja. 13 repos y contando.