Una web que la construye quien la visita. La gente propone qué quiere que
tenga, cada 30 minutos se cierra la votación, y una IA implementa la idea más
repetida, la despliega y la sube a este repositorio. Sin nadie tocando nada.
Si el cambio rompe la web, vuelve atrás sola.
propuestas ventana de 30 min IA producción
┌────────────┐ ┌──────────────────┐ ┌──────────────┐ ┌────────────────┐
│ entras con │ │ se agrupan las │ │ escribe el │ │ compila, verifica
│ GitHub y │ ───▶ │ ideas parecidas │──▶│ código de la │──▶│ y despliega │
│ pides algo │ │ y gana la más │ │ idea ganadora│ │ · si falla, │
└────────────┘ │ repetida │ └──────────────┘ │ vuelve atrás │
└──────────────────┘ └────────────────┘
│ │ │ │
moderación ciclo en la DB revisión del diff commit + push
cycles, con lo descartado y por qué.Bash, WebFetch ni WebSearch.src/ y public/, nunca losmain. Al repositorio solo entraTodo lo que ha ido entrando está en /changelog, y las ideas de la ventana
actual en /ideas.
Poca cosa a propósito: cuanta menos superficie, menos cosas que puede romper la
IA sin que nadie mire.
| Pieza | Qué se usa |
|---|---|
| Framework | Astro 7 en modo servidor, con el adapter de Node |
| Estilos | Tailwind 4, sin build extra (plugin de Vite) |
| Base de datos | SQLite con node:sqlite, el módulo nativo de Node 24 — cero dependencias |
| Sesión | Cookie firmada, sin librería de auth |
| Moderación | Heurística propia + un modelo por HTTP, opcional |
| Proceso | pm2 (o systemd), nginx por delante |
Dependencias de producción: Astro, su adapter de Node, Tailwind y los iconos.
Nada más.
Requiere Node >= 24 por node:sqlite.
git clone git@github.com:midudev/tuweb.dev.git
cd tuweb.dev
pnpm install # instala dependencias
cp .env.example .env # copia la plantilla de variables
pnpm dev # http://localhost:4321
Con el .env de ejemplo tal cual ya funciona: la base de datos se crea sola en
local.db y, si no hay OAuth App configurada, el login usa tu sesión de
gh auth para no obligarte a registrar nada.
Lo único que querrás poner de verdad:
OPENAI_API_KEY — sin ella la moderación se queda solo con la heurística.ANTHROPIC_API_KEY — solo si vas a probar el ciclo completo con la IA.pnpm dev # servidor de desarrollo
pnpm build # compila a dist/
pnpm start # arranca lo compilado, leyendo .env
pnpm process # cierra la ventana: agrupa ideas y elige ganadora
pnpm iterate # el ciclo entero: ventana + IA + verificación + push
pnpm release -- --pull # despliega los cambios del remoto, con vuelta atrás
pnpm rollback # vuelve al último commit que estuvo vivo y sano
pnpm ideas:clear # borra todas las ideas, previa confirmación
pnpm iterate coge un candado (.iterate.lock) para que dos iteraciones no se
pisen. En producción lo lanza un proceso de pm2 cada 30 minutos.
El build no vacía dist/. El servidor que está vivo carga cada ruta cuando se
la piden, y como Astro pone un hash en el nombre de cada chunk, borrar los del
build anterior deja al proceso en marcha pidiendo ficheros que ya no están: esa
ruta devuelve 500 hasta que alguien reinicie. Los restos se tiran solos al final
de la iteración, cuando la versión nueva ya responde.
src/
├── components/ piezas de la interfaz
├── layouts/
├── lib/
│ ├── db/ esquema SQL, cliente y consultas
│ ├── auth.ts sesión y OAuth de GitHub
│ ├── moderation*.ts los dos filtros de las propuestas
│ ├── process-cycle.ts cierre de ventana: agrupar y elegir
│ ├── releases.ts estado del despliegue
│ └── window.ts duración de la ventana y formato
├── middleware.ts CSP y cabeceras de seguridad
└── pages/
├── api/ auth, prompts, cron, health, releases
├── index.astro proponer + lo que ya funciona
├── ideas.astro las ideas de esta ventana
└── changelog.astro lo que la IA ha ido implementando
scripts/
├── iterate.mjs el ciclo completo con la IA
├── release.mjs despliegue con verificación y vuelta atrás
├── rollback.mjs
└── lib/guards.mjs la revisión del diff
Todo lo que escribe la gente es texto de desconocidos que acaba cerca de una IA
con permiso de escritura en el repositorio. Por eso hay cuatro filtros en
cadena, no uno:
src/lib/moderation.ts).src/lib/moderation-llm.ts), con el razonamiento al máximo: es la puerta descripts/lib/guards.mjs): rutasLa IA tiene esos ficheros y src/middleware.ts en su lista negra: no puede
editarlos. Si tocas esa parte, no le quites las defensas.
Además: la web escucha solo en 127.0.0.1 detrás de nginx, el .env es 600 y
nunca entra en git, CRON_SECRET protege los endpoints internos, y el proceso
corre con un usuario sin privilegios.
En un VPS con Ubuntu: nginx delante, la web con pm2 escuchando solo en local, y
HTTPS con Let’s Encrypt. Los despliegues van con pnpm release, que verifica que
la web responde de verdad antes de dar el cambio por bueno y deshace solo si no.
El repositorio trae la configuración de pm2 (ecosystem.config.cjs) y las
unidades de systemd (deploy/) por si prefieres ese camino. Usa uno o el otro,
no los dos.
Apache 2.0. Puedes usarlo, modificarlo y distribuirlo, también en
proyectos comerciales, siempre que mantengas el aviso de copyright y digas qué
has cambiado. Incluye una concesión expresa de patentes.