feat: merge Oasis 0.7.6 upstream — Graphos, E2E, peers/stats, AUTOMATIZACION

Cambios aplicados desde epsylon/oasis 3d46340 (0.7.6):

NUEVO MÓDULO Graphos (mapa interactivo de la red):
- src/views/graphos_view.js (nuevo)

LÓGICA:
- src/backend/nameCache.js (nuevo) — NameAuthor resolver
- src/models/chats_model.js — encriptación E2E
- src/models/calendars_model.js — E2E + calendar invites con códigos
- src/models/maps_model.js — E2E + CLOSED enforcement
- src/models/tribes_model.js — sub-tribe access control (PRESERVA nuestro inviteLog)
- src/models/tribe_crypto.js — soporte E2E
- src/models/main_models.js — refactor (PRESERVA nuestro pub-invite SSB msg)
- src/models/{activity,banking,pads,search,stats,tags,tribes_content}_model.js
- src/backend/backend.js — searchModel constructor + new helpers (errorView, safeRefererRedirect)
- src/backend/blobHandler.js, renderTextWithStyles.js
- src/views/main_views.js — añadido userLink/userLinkLabel + nameCache import (mantiene nuestro hamburger menu)

VISUAL:
- 31 views actualizadas con refactor a userLink helper
- src/views/peers_view.js — tabla con keys clicables
- src/views/stats_view.js — dashboard avanzado
- src/client/assets/styles/style.css — merge (preserva nuestras adiciones QR/mobile)
- Temas desktop: Clear, Dark, Matrix, Purple
- Translations 11 idiomas (ar, de, en, es, eu, fr, hi, it, pt, ru, zh)
- src/configs/{config-manager,oasis-config}, server/SSB_server.js, oasis_client.js

SKIPS (intencionalmente):
- OasisMobile.css del upstream (mantenemos NUESTRO mobile.css y theme)
- main_views.js menu reorganization (mantenemos hamburger nav)
- @xenova/transformers (LLM, no viable mobile)
- node-llama-cpp (build nativo no soportado en arm64 mobile)
- pdfjs-dist (pendiente probar luego)
- AI/embedder.js + AI/routes_index.js (dependen de las libs LLM)

server/package.json: version 0.7.5 → 0.7.6

AUTOMATIZACIÓN:
- Nueva carpeta AUTOMATIZACION/ con 10 archivos:
  - 4 opciones (cron simple, multi-agente, GitHub Actions, webhook)
  - Setup Debian completo paso a paso
  - Scripts bash listos: scout, merger, builder, notify-telegram
  - Prompts listos para los agentes
  - Sección /testing-app para 0asis.net
  - Human-in-the-loop: archivos prohibidos para auto-merge

PENDIENTE: build APK (el bash tool tuvo timeouts; usar comandos
de CONTEXT/cambio_apk_repack.txt manualmente).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
SITO 2026-05-15 19:41:45 +02:00
parent 13161b2158
commit 3a3563f2a0
84 changed files with 5842 additions and 1621 deletions

View file

@ -0,0 +1,79 @@
===============================================================
AUTOMATIZACIÓN — Oasis Mobile APK auto-update
Creado: 2026-05-09
===============================================================
OBJETIVO
--------
Automatizar la actualización de la APK de Oasis Mobile cuando se
publique una nueva versión del upstream (epsylon/oasis), sin
intervención manual semanal.
ESCENARIO IDEAL
---------------
1. Epsylon publica Oasis v0.7.7 en GitHub.
2. Un webhook / cron lo detecta.
3. Claude analiza el diff y aplica cambios seguros.
4. Construye y firma la APK.
5. La sube a 0asis.net/testing-app.
6. Te avisa por Telegram.
7. Tú compruebas, y si OK, mueves de "testing" a "release".
ARCHIVOS DE ESTA CARPETA
------------------------
00_INDICE.txt
Este archivo.
01_OPCIONES.txt
Las 4 opciones de automatización con pros/contras.
Útil para decidir cuál implementar primero.
02_OPCION_A_cron_simple.txt
Opción A: cron + claude headless. Setup más sencillo.
Pasos exactos para configurar en Debian.
03_OPCION_B_multiagente.txt
Opción B: 3 agentes (scout / merger / builder).
Recomendada — modular y a prueba de fallos.
04_OPCION_C_github_actions.txt
Opción C: GitHub Action en el fork de oasis_mobile.
Gratis, auditable, con artifacts descargables.
05_OPCION_D_webhook_reactivo.txt
Opción D: webhook reactivo a releases.
Lo más rápido en reaccionar, requiere VPS público.
06_TESTING_APP_seccion.txt
Cómo montar la sección /testing-app en 0asis.net
para distribuir builds beta automáticas.
07_HUMAN_IN_THE_LOOP.txt
Por qué no fully-auto: archivos que SIEMPRE requieren
revisión humana antes de aplicar (main_views, mobile.css).
Lista de "luces rojas" que el agente debe detectar.
08_PROMPTS_para_agentes.md
Los prompts exactos que usan los agentes.
Listos para copiar/pegar a claude -p.
09_SCRIPTS.md
Scripts bash listos para usar (cron entry, build APK,
notificación Telegram, deploy a 0asis.net).
10_DEBIAN_setup.txt
Pasos concretos para preparar el server Debian:
instalación de Claude Code, gh CLI, Android SDK, etc.
DECISIÓN RECOMENDADA
--------------------
Empezar por **Opción B + D combinadas**:
- Webhook GitHub release → dispara scout (D)
- Scout abre tarea con reporte
- Tú revisas (5 min lectura)
- Merger + Builder corren solos (B)
- Telegram notifica con APK lista
Tiempo de setup inicial: 1 día.
Tiempo manual semanal después: 5 min de revisión.

View file

@ -0,0 +1,102 @@
===============================================================
OPCIONES DE AUTOMATIZACIÓN — Comparativa
===============================================================
OPCIÓN A — CRON + CLAUDE HEADLESS (SIMPLE)
==========================================
Un cron semanal en Debian. Un único script que invoca claude
con un prompt grande pidiendo que lo haga todo de cabo a rabo.
PROS:
- Setup en 30 minutos
- Sin infra extra (solo cron)
- Cero costes adicionales
CONTRAS:
- Un único punto de fallo
- Si claude se atasca en un conflicto, todo se queda colgado
- Sin recuperación parcial
- Difícil debuggear cuándo va mal
CUÁNDO USARLA:
- Cuando solo se quiere probar el concepto
- Cuando los cambios upstream son pequeños y predecibles
OPCIÓN B — MULTI-AGENTE (RECOMENDADA)
=====================================
Tres agentes especializados en cron. Cada uno con su prompt
corto, su contexto, y su responsabilidad clara.
scout | Lun 03:00 | git fetch + analiza diff + reporta
merger | Lun 04:00 | aplica cambios safe + abre PR
builder | Lun 05:00 | build APK + sube + notifica
PROS:
- Fallo aislado (si scout falla, merger no se ejecuta)
- Prompts cortos = menos tokens = más barato y fiable
- Logs separados por agente
- Recuperable: puedes re-ejecutar solo el que falló
- Auditable: cada agente deja su reporte en disco
CONTRAS:
- Más setup inicial (3 crons, 3 prompts)
- Hay que orquestar dependencias (merger depende de scout)
CUÁNDO USARLA:
- Cuando los cambios upstream son frecuentes y variados
- Cuando quieres ver QUÉ va a aplicar antes de aplicarlo
OPCIÓN C — GITHUB ACTIONS
=========================
Workflow en .github/workflows/weekly-merge.yml del repo
oasis_mobile. Trigger en cron + manual dispatch.
PROS:
- Gratis (2000 min/mes en repo público o privado básico)
- Histórico completo de runs visible
- Artifacts descargables (la APK)
- Logs públicos si lo quieres
- Cero infraestructura propia
CONTRAS:
- Timeout máximo 6h por job
- Build APK consume bastante (10-15 min)
- El repo debe estar en GitHub (no en Gitea code.03c8.net)
- Secrets: ANTHROPIC_API_KEY visible para todos los maintainers
CUÁNDO USARLA:
- Si planeas mover el repo a GitHub
- Si no tienes VPS o no quieres gestionarlo
OPCIÓN D — WEBHOOK REACTIVO
===========================
Webhook de GitHub apuntando a un endpoint en tu VPS. Cuando
epsylon publica un release, dispara inmediatamente el pipeline.
PROS:
- Reacción casi en tiempo real (segundos)
- No esperas al cron del lunes
- El pipeline puede ser tan complejo como quieras
CONTRAS:
- Requiere VPS público con dominio + HTTPS
- Hay que mantener el endpoint
- Si el webhook falla, hay que tener un cron de respaldo
CUÁNDO USARLA:
- Cuando quieres lo más rápido posible
- Cuando tienes ya un VPS funcionando
COMBINACIÓN RECOMENDADA: B + D
==============================
- Webhook (D) dispara scout (de B)
- Cron de seguridad cada lunes 03:00 también ejecuta scout
(por si el webhook falla)
- Resto del pipeline (merger + builder) es B
Mejor de los dos mundos: rápido pero con respaldo, modular,
auditable, recuperable.

View file

@ -0,0 +1,122 @@
===============================================================
OPCIÓN A — CRON + CLAUDE HEADLESS
===============================================================
ARQUITECTURA
------------
cron (lunes 03:00) → bash script → claude -p "..." → APK lista
REQUISITOS EN EL VPS DEBIAN
---------------------------
- Claude Code instalado y autenticado (claude login)
- Git CLI
- Android SDK build-tools (zipalign, apksigner)
- Keystore copiado: /home/sito/oasis-release-key.jks
- Clon del repo oasis_mobile en /opt/oasis_mobile
- Acceso al upstream: git remote add upstream
https://github.com/epsylon/oasis.git
- ANTHROPIC_API_KEY exportada en .bashrc del usuario
ESTRUCTURA DE ARCHIVOS
----------------------
/opt/oasis_mobile/
.git/
nodejs-project/...
CONTEXT/
AUTOMATIZACION/
/opt/scripts/
oasis-auto-update.sh <- script principal
oasis-build-apk.sh <- build/sign APK
oasis-notify-telegram.sh <- enviar APK por bot
/var/log/oasis-auto/
YYYY-MM-DD.log <- logs por ejecución
CRON ENTRY
----------
0 3 * * 1 /opt/scripts/oasis-auto-update.sh \
> /var/log/oasis-auto/$(date +\%Y-\%m-\%d).log 2>&1
ESQUELETO DEL SCRIPT (oasis-auto-update.sh)
-------------------------------------------
#!/bin/bash
set -euo pipefail
cd /opt/oasis_mobile
git fetch upstream
HEAD_OLD=$(git rev-parse HEAD)
UPSTREAM_HEAD=$(git rev-parse upstream/main)
if [ "$HEAD_OLD" = "$UPSTREAM_HEAD" ]; then
echo "No hay cambios upstream. Salgo."
exit 0
fi
# Crear branch para el intento
BRANCH="auto-merge-$(date +%Y%m%d)"
git checkout -b "$BRANCH"
# Invocar claude con el prompt
claude -p "$(cat /opt/scripts/prompts/auto-merge.md)" \
--allowed-tools "Read,Write,Edit,Bash"
# Build APK si no hay conflictos
if ! git diff --name-only --diff-filter=U | grep -q .; then
bash /opt/scripts/oasis-build-apk.sh
bash /opt/scripts/oasis-notify-telegram.sh \
"APK $(date +%Y-%m-%d) lista en /opt/oasis_mobile/apk/"
else
bash /opt/scripts/oasis-notify-telegram.sh \
"Conflictos en merge automático. Revisa $BRANCH."
fi
PROMPT BASE PARA CLAUDE
-----------------------
Lee CONTEXT/cambio_apk_repack.txt y CONTEXT/tareas_usabilidad.txt
para entender el proyecto.
Tu tarea:
1. Compara HEAD con upstream/main.
2. Aplica SOLO cambios safe a la rama actual:
- views nuevos (graphos_view, markdown.js, etc)
- models nuevos (preservando inviteLog en tribes_model)
- translations (todos los idiomas)
- peers_view, stats_view (visuales)
3. NO toques:
- main_views.js
- assets/themes/OasisMobile.css
- assets/styles/mobile.css
- server/package.json (deps: @xenova/transformers, node-llama-cpp)
4. Si encuentras conflictos en archivos críticos, NO los resuelvas
automáticamente. Deja el conflicto marker y termina.
5. Commit con mensaje "feat: merge upstream vX.Y.Z (auto)"
y co-author Claude.
Reporta qué archivos copiaste, cuáles dejaste, y cualquier
conflicto encontrado.
PROS DE ESTA OPCIÓN
-------------------
- Setup en 1 hora
- Sin orquestación compleja
- Cron + log = simple de debuggear
CONTRAS
-------
- Un único prompt grande puede fallar parcialmente
- Si claude se queda sin context, no se entera de ello
- Difícil intervenir a mitad
CUÁNDO MIGRAR A OTRA OPCIÓN
---------------------------
Si al 3er intento sale algo mal automatizado, pasar a opción B
(multi-agente). El coste extra de setup vale la pena para tener
fallos aislados y reportes parciales.

View file

@ -0,0 +1,145 @@
===============================================================
OPCIÓN B — MULTI-AGENTE (RECOMENDADA)
===============================================================
ARQUITECTURA
------------
Lunes 03:00 — SCOUT
Detecta cambios upstream, genera reporte JSON con:
- Lista de archivos cambiados
- Categorización (safe / review / skip)
- Resumen de cada cambio
Output: /var/oasis-auto/reports/YYYY-MM-DD-scout.json
/var/oasis-auto/reports/YYYY-MM-DD-scout.md (humano)
Notifica Telegram: "Reporte semanal listo, revisa /scout"
Lunes 04:00 — MERGER
Lee scout.json. Si está marcado como "approved" (manual
o automático según safety level), aplica los cambios
safe + abre branch con merge para los review.
Output: /var/oasis-auto/reports/YYYY-MM-DD-merger.md
Notifica Telegram: "Branch auto-merge-X creada, lista build"
Lunes 05:00 — BUILDER
Verifica que no haya conflictos en working tree.
Hace build APK + firma + sube a /testing-app.
Output: /var/oasis-auto/apks/oasis-YYYY-MM-DD.apk
Notifica Telegram: con link a la APK
FLUJO DETALLADO
---------------
1. scout corre cron
├─ git fetch upstream
├─ git log HEAD..upstream/main --stat → lista de cambios
├─ Para cada archivo cambiado:
│ - Aplica reglas de clasificación (safe / review / skip)
│ - Genera resumen breve del cambio
├─ Escribe scout.json + scout.md
└─ Telegram bot: "Reporte listo en {URL}"
2. (HUMANO, opcional) revisa scout.md y aprueba con:
curl -X POST https://your-vps.com/api/approve/YYYY-MM-DD
o solo deja que el cron continúe (auto-aprobar si "safety_score" > 0.8)
3. merger corre cron
├─ Lee scout.json
├─ Si !approved AND auto_approve=false: salir y notificar
├─ git checkout -b auto-merge-YYYY-MM-DD
├─ Para cada archivo "safe": git checkout upstream/main -- $file
├─ Para cada archivo "review": deja conflict marker
├─ Para cada archivo "skip": ignora
├─ git commit -m "feat: auto-merge upstream v$VERSION"
└─ Telegram bot: "Branch lista, building..."
4. builder corre cron
├─ Verifica working tree limpio
├─ bash build-apk.sh
├─ Sube APK a /testing-app endpoint
└─ Telegram bot: "APK lista: {URL}"
CRON ENTRIES
------------
0 3 * * 1 /opt/scripts/oasis-scout.sh
0 4 * * 1 /opt/scripts/oasis-merger.sh
0 5 * * 1 /opt/scripts/oasis-builder.sh
SISTEMA DE CLASIFICACIÓN AUTO
-----------------------------
El scout aplica estas reglas:
SAFE (auto-aplicar):
✓ src/views/*_view.js si es nuevo file (no existía antes)
✓ src/views/markdown.js (helper nuevo)
✓ src/client/assets/translations/*.js (todos)
✓ src/client/assets/themes/Clear-SNH.css
✓ src/client/assets/themes/Dark-SNH.css
✓ src/client/assets/themes/Matrix-SNH.css
✓ src/client/assets/themes/Purple-SNH.css
REVIEW (necesita mirada humana):
⚠ src/models/* (puede conflictuar con nuestro inviteLog)
⚠ src/backend/backend.js (rutas + constructors)
⚠ src/views/main_views.js (NUESTRO menú hamburger)
⚠ src/views/blockchain_view.js (puede tener inviteLog refs)
⚠ src/views/tribes_view.js
⚠ src/client/assets/styles/style.css
⚠ src/server/package.json (puede traer deps no compatibles)
SKIP (NUNCA aplicar):
✗ src/client/assets/themes/OasisMobile.css
✗ src/client/assets/styles/mobile.css
✗ src/client/public/js/mobile-ui.js
✗ src/views/mobile_pager.js (es nuestro)
✗ dependencies: @xenova/transformers, node-llama-cpp
REPORTES (formato scout.md)
---------------------------
# Oasis upstream sync — 2026-05-09
Upstream: v0.7.5 → v0.7.6 (3 commits, +4349/-1266)
## Safe (aplicar auto): 12 archivos
- [+] src/views/graphos_view.js (nuevo, 245 líneas)
- [+] src/views/markdown.js (nuevo, 80 líneas)
- [M] src/client/assets/translations/oasis_es.js (+24 strings)
- ...
## Review (revisar manual): 6 archivos
- [M] src/models/tribes_model.js — afecta a inviteLog, revisar
- [M] src/views/main_views.js — añade ítem menu en Tools, NO aplicar
- ...
## Skip: 3 archivos
- [M] src/client/assets/themes/OasisMobile.css
- [M] src/client/assets/styles/mobile.css
- server/package.json (deps prohibidos)
## Acciones recomendadas
- Auto-merge: yes
- Conflict score: 0.2 (bajo)
- Build APK: yes
VENTAJAS CRÍTICAS
-----------------
1. Cada agente tiene su prompt corto → menos tokens → más fiable
2. Logs separados → fácil debuggear
3. Recuperable: si builder falla, re-ejecutas solo builder
4. Auditable: histórico de scouts.json en /var/oasis-auto/reports
5. Reversible: cada merge en su branch, fácil de revertir
NIVEL DE AUTOMATIZACIÓN AJUSTABLE
---------------------------------
Variable AUTO_APPROVE_THRESHOLD en /opt/scripts/config:
1.0 = nunca auto, siempre humano aprueba
0.7 = auto si scout reporta "conflict_score < 0.3"
0.0 = todo auto (no recomendado)
Empezar en 1.0, después de 4 semanas exitosas bajar a 0.7.

View file

@ -0,0 +1,115 @@
===============================================================
OPCIÓN C — GITHUB ACTIONS
===============================================================
REQUISITO PREVIO
----------------
Mover el repo oasis_mobile a GitHub (público o privado).
Actualmente está en Gitea code.03c8.net:3000.
Razón: GitHub Actions solo corre en repos de GitHub.
ARCHIVO: .github/workflows/upstream-sync.yml
--------------------------------------------
name: Upstream sync (weekly)
on:
schedule:
- cron: '0 3 * * 1' # Lunes 03:00 UTC
workflow_dispatch: {} # también manual
jobs:
sync-and-build:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Add upstream remote
run: |
git remote add upstream https://github.com/epsylon/oasis.git
git fetch upstream
- name: Check for upstream changes
id: check
run: |
BEHIND=$(git rev-list HEAD..upstream/main --count)
echo "behind=$BEHIND" >> $GITHUB_OUTPUT
- name: Setup Claude Code
if: steps.check.outputs.behind != '0'
uses: anthropics/claude-code-action@v1
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt-file: .github/prompts/upstream-merge.md
- name: Install Android SDK
if: steps.check.outputs.behind != '0'
uses: android-actions/setup-android@v3
- name: Build APK
if: steps.check.outputs.behind != '0'
run: bash .github/scripts/build-apk.sh
env:
KEYSTORE_PASS: ${{ secrets.KEYSTORE_PASS }}
- name: Upload APK artifact
if: steps.check.outputs.behind != '0'
uses: actions/upload-artifact@v4
with:
name: oasis-mobile-apk-${{ github.run_number }}
path: /tmp/oasis-aligned.apk
retention-days: 30
- name: Create release
if: steps.check.outputs.behind != '0'
uses: softprops/action-gh-release@v1
with:
tag_name: auto-${{ github.run_number }}
files: /tmp/oasis-aligned.apk
prerelease: true
SECRETS A CONFIGURAR EN GITHUB
------------------------------
ANTHROPIC_API_KEY <- API key de Anthropic
KEYSTORE_PASS <- "oasis123"
KEYSTORE_BASE64 <- base64 del oasis-release-key.jks
TELEGRAM_BOT_TOKEN <- opcional para notificar
PROS
----
- Gratis (2000 minutos/mes en repo privado, ilimitado público)
- Histórico completo y auditable
- Artifacts descargables 30 días
- Crea release de pre-release automáticamente
- Sin VPS, sin mantenimiento de infra
CONTRAS
-------
- Hay que mover el repo a GitHub
- Build APK consume ~10-15 min, costo eficiencia OK
- Si la API key se filtra, alguien podría gastar tu cuenta
- Si Anthropic baja prices o cambia API, hay que actualizar
COSTE ESTIMADO
--------------
GitHub Actions: 0 €/mes (dentro del free tier)
Anthropic API: ~0.50€ por sync semanal x 4 = 2€/mes
Total: 2€/mes vs VPS 5-10€/mes para opción A/B/D
CUÁNDO ES MEJOR ESTA OPCIÓN
---------------------------
- Si no tienes/quieres mantener un VPS
- Si te da igual mover el repo a GitHub
- Si quieres logs públicos auditables
- Si quieres distribución automática de pre-releases

View file

@ -0,0 +1,136 @@
===============================================================
OPCIÓN D — WEBHOOK REACTIVO
===============================================================
ARQUITECTURA
------------
GitHub publica un release
Webhook POST → tu VPS:5000/api/oasis-release
El endpoint dispara el pipeline (B u otro)
APK lista en minutos
COMPONENTES NECESARIOS
----------------------
- VPS público con HTTPS (Let's Encrypt vale)
- Dominio o IP fija
- Nginx o Caddy como reverse proxy
- Servicio webhook receiver (Python Flask / Node Express / Go)
- Secret compartido para verificar firma de GitHub
WEBHOOK CONFIG EN GITHUB (en repo oasis_mobile fork)
-----------------------------------------------------
Settings → Webhooks → Add webhook
Payload URL: https://your-vps.com/api/oasis-release
Content type: application/json
Secret: <generar 32 bytes random>
Events: only "Releases"
NOTA IMPORTANTE: GitHub solo dispara webhooks de TU repo,
no del repo upstream de epsylon. Hay dos formas:
a) Hacer fork de oasis y configurar webhook ahí
- Cada push del upstream se replica si tienes
sync activo
b) Poll periódico al upstream desde tu VPS y dispara
internamente cuando detectas nuevo release
- Más simple, no requiere fork
- Recomendado
RECEIVER ENDPOINT (Flask, en Python)
-------------------------------------
/opt/oasis-webhook/app.py:
from flask import Flask, request, abort
import hmac, hashlib, subprocess
app = Flask(__name__)
SECRET = open("/opt/oasis-webhook/secret").read().strip()
@app.post("/api/oasis-release")
def release():
sig = request.headers.get("X-Hub-Signature-256", "")
mac = hmac.new(SECRET.encode(), request.data, hashlib.sha256)
expected = "sha256=" + mac.hexdigest()
if not hmac.compare_digest(sig, expected):
abort(401)
event = request.headers.get("X-GitHub-Event")
if event != "release":
return "skip", 200
payload = request.json
action = payload.get("action")
if action == "published":
tag = payload["release"]["tag_name"]
subprocess.Popen(["/opt/scripts/oasis-scout.sh", "--tag", tag])
return "ok", 200
ALTERNATIVA POLL (sin webhook, más simple)
-------------------------------------------
Cada 30 min un cron consulta:
curl -s https://api.github.com/repos/epsylon/oasis/releases/latest
Si el tag es nuevo (no está en /var/oasis-auto/seen-tags.txt):
1. Añadir a seen-tags
2. Disparar scout
SYSTEMD SERVICE (recomendado para uptime)
------------------------------------------
/etc/systemd/system/oasis-webhook.service:
[Unit]
Description=Oasis webhook receiver
After=network.target
[Service]
User=oasis
WorkingDirectory=/opt/oasis-webhook
ExecStart=/usr/bin/python3 -m gunicorn -b 127.0.0.1:5000 app:app
Restart=always
[Install]
WantedBy=multi-user.target
CADDY CONFIG (reverse proxy)
----------------------------
/etc/caddy/Caddyfile:
your-vps.com {
handle /api/oasis-release {
reverse_proxy 127.0.0.1:5000
}
handle /testing-app/* {
root * /var/oasis-auto/apks
file_server browse
}
}
PROS
----
- Reacción casi en tiempo real (segundos)
- No esperas al lunes
- Si combina con cron de respaldo, robusto
CONTRAS
-------
- Requiere VPS público con dominio
- Hay que gestionar HTTPS (Caddy/Let's Encrypt lo hace fácil)
- Si el webhook falla por red, hay que tener fallback
RECOMENDACIÓN: COMBINAR WEBHOOK + CRON DE RESPALDO
---------------------------------------------------
Webhook dispara scout inmediatamente cuando hay release.
Cron semanal lunes 03:00 también dispara scout para no
perder oportunidades si el webhook falló.
Scout debe ser idempotente: si ya procesó el commit X,
no debe procesarlo de nuevo.

View file

@ -0,0 +1,147 @@
===============================================================
SECCIÓN /testing-app EN 0asis.net
===============================================================
OBJETIVO
--------
Tener una URL pública (ej: 0asis.net/testing-app) donde
automáticamente se publican las APK beta generadas por la
automatización. Los usuarios beta-testers pueden descargar y
probar antes de que se libere oficialmente.
ESTRUCTURA RECOMENDADA
----------------------
https://0asis.net/ -- web principal pública
https://0asis.net/testing-app/ -- index de beta APKs
https://0asis.net/testing-app/latest -- siempre la última
https://0asis.net/testing-app/archive -- histórico
IMPLEMENTACIÓN
--------------
OPCIÓN A: Carpeta estática servida por Nginx/Caddy
--------------------------------------------------
Más simple. Cuando el builder termina de generar la APK:
cp /tmp/oasis-aligned.apk /var/www/0asis.net/testing-app/
oasis-v0.7.6-20260509-pruebas.apk
ln -sf oasis-v0.7.6-20260509-pruebas.apk
/var/www/0asis.net/testing-app/latest.apk
Caddyfile:
0asis.net {
handle /testing-app/* {
root * /var/www/0asis.net
file_server browse
@latest path /testing-app/latest.apk
header @latest Content-Disposition "attachment; filename=oasis-latest-pruebas.apk"
}
handle {
# web principal
}
}
OPCIÓN B: Index dinámico con metadatos
--------------------------------------
El index muestra una tabla con cada APK, fecha, changelog,
link de descarga. Más útil para usuarios.
Generar /var/www/0asis.net/testing-app/index.html
automáticamente al final de builder.sh:
<h1>Oasis Mobile - Testing builds</h1>
<table>
<tr><th>Versión</th><th>Fecha</th><th>Cambios</th><th>Download</th></tr>
<tr>
<td>v0.7.6</td>
<td>2026-05-09</td>
<td>Graphos, encriptación E2E, peers...</td>
<td><a href="oasis-v0.7.6-20260509-pruebas.apk">APK</a></td>
</tr>
...
</table>
OPCIÓN C: Página dinámica con Caddy + tag de release
----------------------------------------------------
Más profesional: una página que lee el último JSON generado
por builder y renderiza UI bonita con changelog.
CHANGELOG AUTOMÁTICO
--------------------
El scout puede generar un changelog.md amigable. Por ejemplo:
## v0.7.6 — 2026-05-09 (beta)
### Nuevas funcionalidades
- Graphos: visualización interactiva de la red
- AINav (deshabilitado en móvil, requiere LLM)
- Encriptación E2E para chats / calendarios / mapas
- Cascada al borrar tribes
### Bugfixes
- Resolución de carreras en updates concurrentes
### Cambios visuales
- Tabla de peers mejorada
- Dashboard de estadísticas
[Descargar APK](oasis-v0.7.6-20260509-pruebas.apk)
Este markdown puede renderizarse a HTML con `pandoc` o
incluirse tal cual en una página estática.
SEGURIDAD DE LA SECCIÓN /testing-app
------------------------------------
- Considera proteger /testing-app con HTTP basic auth
para que solo beta-testers tengan acceso:
Caddyfile:
basicauth /testing-app/* {
tester $2a$14$<bcrypt-hash>
}
- O usar tokens en URL: /testing-app/{token}/latest.apk
- La APK lleva tu firma — cualquiera con ella puede
instalar. Si te preocupa el leak, mantén privado.
INTEGRACIÓN CON TELEGRAM
------------------------
Al final del builder, además de subir la APK al servidor:
bash oasis-notify-telegram.sh \
"Nueva APK lista para test: \
https://0asis.net/testing-app/oasis-v0.7.6-20260509-pruebas.apk \
[Cambios](https://0asis.net/testing-app/v0.7.6-changelog.html)"
Los beta-testers en el canal de Telegram reciben el aviso al
instante y pueden instalar sin abrir email ni nada.
MIGRACIÓN A "RELEASE OFICIAL"
-----------------------------
Cuando una versión beta pasa el período de prueba (ej: 1 semana
sin reportes), tú manualmente la copias a /release/:
cp /var/www/0asis.net/testing-app/oasis-v0.7.6-20260509-pruebas.apk
/var/www/0asis.net/release/oasis-v0.7.6.apk
ln -sf oasis-v0.7.6.apk /var/www/0asis.net/release/latest.apk
Y publicas en redes / Telegram canal release.
ARCHIVO DE BUILDS HISTÓRICAS
-----------------------------
Configura una limpieza para no llenar el disco:
/etc/cron.daily/oasis-cleanup:
find /var/www/0asis.net/testing-app -name "oasis-*.apk" \
-mtime +60 -delete
Mantiene los últimos 60 días de builds beta.

View file

@ -0,0 +1,162 @@
===============================================================
HUMAN-IN-THE-LOOP — Lo que NO puede automatizarse 100%
===============================================================
POR QUÉ NO ES VIABLE EL FULL-AUTO
---------------------------------
Hay archivos donde el upstream y nuestro fork divergen
intencionadamente. Aplicar automáticamente el upstream
ROMPERÍA nuestra app móvil.
Estos archivos SIEMPRE requieren revisión humana antes de
aplicar cualquier cambio.
LISTA DE ARCHIVOS "PROHIBIDOS" PARA AUTO-MERGE
----------------------------------------------
src/client/assets/themes/OasisMobile.css
Razón: Es nuestro tema de móvil, escrito desde cero.
El upstream lo trata como tema de escritorio.
Aplicar el de upstream rompería: hamburger nav, QR
lightbox, panel-quicklinks, sidebar-panel drawer.
src/client/assets/styles/mobile.css
Razón: 100% nuestro. Contiene el paginador actpager,
safe-area iOS, header móvil de 1-fila + 2-fila, todo
el sistema mobile.
src/client/public/js/mobile-ui.js
Razón: Ya no se usa (paginador pasó a CSS-only) pero
si upstream añade un mobile-ui.js distinto, NO copiar.
src/views/mobile_pager.js
Razón: Helper nuestro, no existe en upstream.
src/views/main_views.js
Razón: Contiene nuestro menú hamburger CSS-only,
sidebar-panel drawer, panel-quicklinks. El upstream
no tiene esto. Aplicar pisaría todo nuestro layout.
EXCEPCIÓN: Si solo cambian textos / strings i18n,
se puede hacer merge cuidadoso. Pero requiere mirada.
src/views/inhabitants_view.js
Razón: Tiene nuestros QR codes integrados (qr-share
con <details>/<summary>). El upstream no.
Hay que merge manual preservando los QR.
src/views/invites_view.js
Razón: Tiene nuestros QR por cada pub + IIFE async
+ inviteLog renderInviteExtra.
src/views/tribes_view.js
Razón: QR de tribe invite + nuestros campos del form
(isAnonymous, isLARP, isSubEdit).
src/models/tribes_model.js
Razón: Tiene NUESTRO inviteLog (generateInvite +
joinByInvite). El upstream no. Si copiamos, perdemos
la trazabilidad de invites.
src/models/main_models.js
Razón: Publica SSB msg type:'pub-invite' al aceptar
pub invite. Es nuestro.
src/backend/backend.js
Razón: Tiene rutas custom (POST /settings/invite/accept,
nuestro orden de constructores). Cualquier cambio
upstream debe integrarse manualmente.
src/configs/config-manager.js
Razón: Defaults modificados (wish, pmVisibility,
economy modules on, etc).
src/server/package.json
Razón: NO añadir las deps nuevas del upstream:
- @xenova/transformers (60MB+)
- node-llama-cpp (no funciona arm64 mobile)
- pdfjs-dist (pendiente probar, anotar para luego)
src/client/middleware.js
Razón: Tiene 'unsafe-inline' en CSP necesario para
nosotros + mounts /game-assets /maptiles /mapcache
custom + frame-src 'self'.
LISTA DE ARCHIVOS "SAFE" PARA AUTO-MERGE
----------------------------------------
src/client/assets/translations/*.js
Las traducciones son aditivas. Pueden copiarse al
100% del upstream sin riesgo.
src/client/assets/themes/Clear-SNH.css
src/client/assets/themes/Dark-SNH.css
src/client/assets/themes/Matrix-SNH.css
src/client/assets/themes/Purple-SNH.css
Temas de escritorio, no afectan a móvil.
src/views/*_view.js (NUEVOS)
Si el archivo no existe en nuestro fork, copia auto.
Ej: graphos_view.js, markdown.js.
src/views/peers_view.js
src/views/stats_view.js
src/views/courts_view.js
src/views/parliament_view.js
Vistas que no tienen nuestros customizations, safe
para refresh completo.
src/models/*.js (NUEVOS)
Si es un modelo nuevo, copia auto.
docs/CHANGELOG.md
Copia auto, solo es informativo.
SEÑALES DE ALARMA QUE EL AGENTE DEBE DETECTAR
---------------------------------------------
Si el scout detecta cualquiera de estos patrones en el
diff, debe marcar la sync entera como "needs human":
- Cambios en mobile.css / OasisMobile.css del upstream
(no debería pasar, pero si pasa, alguien añadió tema
móvil al upstream y hay que decidir qué hacer)
- Nuevas dependencias en server/package.json que no
están en una whitelist conocida
- Cambios en CSP de middleware.js que reduzcan permisos
- Cambios en SSB_server.js que afecten al modo public
de nuestro APK
- Cambios en blobHandler.js (lo modificamos a veces)
DECISIÓN POR DEFECTO
--------------------
Cuando el scout no puede decidir con seguridad:
"Si tengo duda, marcar como REVIEW. Es preferible que
el humano apruebe cinco minutos a romper la APK."
PROCESO DE REVISIÓN HUMANA (5 min lunes mañana)
------------------------------------------------
1. Abrir scout.md generado el lunes 03:00
2. Lectura rápida de la lista SAFE (debe verse razonable)
3. Lectura cuidadosa de la lista REVIEW
4. Si todo OK: curl POST /api/approve o nada (auto-approve)
5. Si algo no OK: ejecutar manualmente claude con prompt
específico para ese conflicto
6. El builder corre solo a las 05:00
REGLA DE ORO
------------
NUNCA bajar AUTO_APPROVE_THRESHOLD por debajo de 0.5.
Mejor perder 5 min revisando que perder 2 horas
reconstruyendo la APK porque un cambio rompió algo.

View file

@ -0,0 +1,168 @@
# Prompts para los agentes
Copia/pega cada prompt al script correspondiente.
## SCOUT (lunes 03:00)
```
Eres el agente SCOUT de Oasis Mobile auto-update.
Contexto:
- Repo local: /opt/oasis_mobile
- Upstream: https://github.com/epsylon/oasis.git (remote `upstream`)
- Lee CONTEXT/cambio_apk_repack.txt y AUTOMATIZACION/07_HUMAN_IN_THE_LOOP.txt
para entender qué archivos son prohibidos y cuáles safe.
Tu tarea:
1. `git fetch upstream`
2. Identifica el último tag / commit del upstream/main.
3. Compara con nuestro HEAD: lista cada archivo cambiado.
4. Para cada archivo aplica las reglas de clasificación:
- SAFE = aplicar auto (translations, themes desktop, archivos
nuevos que no existen en local)
- REVIEW = requiere mirada humana (models, backend, views con
customizations nuestras)
- SKIP = nunca aplicar (mobile.css, OasisMobile.css,
server/package.json con deps prohibidas)
5. Para cada archivo SAFE y REVIEW, genera un resumen de 1-2
líneas del cambio.
6. Escribe el reporte en formato JSON Y formato Markdown legible:
- /var/oasis-auto/reports/$(date +%Y-%m-%d)-scout.json
- /var/oasis-auto/reports/$(date +%Y-%m-%d)-scout.md
7. Calcula un "conflict_score" entre 0.0 (sin conflictos) y 1.0
(muchos archivos REVIEW). Inclúyelo en el JSON.
8. NO hagas merge. Solo analiza.
9. Notifica Telegram con link al reporte.
Tu output debe ser breve y estructurado.
Si encuentras algún archivo PROHIBIDO modificado en upstream
(ej: OasisMobile.css), márcalo como FATAL en el reporte y
recomienda no auto-aprobar.
```
## MERGER (lunes 04:00)
```
Eres el agente MERGER de Oasis Mobile auto-update.
Contexto:
- Lee el último scout.json en /var/oasis-auto/reports/
- Lee CONTEXT/cambio_apk_repack.txt
- Lee AUTOMATIZACION/07_HUMAN_IN_THE_LOOP.txt
Tu tarea:
1. Verifica que existe scout.json reciente (<24h).
2. Lee approval_status del reporte:
- "approved" o conflict_score < AUTO_APPROVE_THRESHOLD
→ procede
- cualquier otra cosa → salir y notificar
3. Crea branch: `git checkout -b auto-merge-$(date +%Y%m%d)`
4. Para cada archivo "safe" del reporte:
`git checkout upstream/main -- $file`
5. Para cada archivo "review" del reporte:
- Generar diff
- Si el diff es pequeño (<30 líneas) y NO toca patrones
prohibidos (inviteLog, QR, hamburger, mobile-pager,
unsafe-inline): aplicar
- Si no: dejar el archivo intacto y marcar como pending
6. Para cada archivo "skip": ignorar
7. Verifica con `git status` que no hay archivos sin trackear
inesperados.
8. Verifica syntax con `node --check` en cada .js modificado.
9. Si todo OK:
`git commit -m "feat: merge upstream v$VERSION (auto)"`
10. Escribe reporte merger.md con qué archivos aplicaste.
11. Notifica Telegram.
NUNCA modifiques estos archivos:
- src/client/assets/themes/OasisMobile.css
- src/client/assets/styles/mobile.css
- src/client/public/js/mobile-ui.js
- src/views/mobile_pager.js
- src/views/main_views.js (excepto i18n strings sin layout)
Si tienes dudas en cualquier paso, NO procedas. Genera un
reporte explicando y termina.
```
## BUILDER (lunes 05:00)
```
Eres el agente BUILDER de Oasis Mobile auto-update.
Contexto:
- Lee CONTEXT/cambio_apk_repack.txt para los pasos exactos
de build.
- Lee AUTOMATIZACION/06_TESTING_APP_seccion.txt para saber
dónde subir la APK.
Tu tarea:
1. Verifica que estás en una branch auto-merge-*.
2. Verifica working tree limpio: `git status --porcelain`
debe estar vacío.
3. Verifica que no hay markers de merge sin resolver:
`grep -rn "<<<<<<< HEAD" src/` debe estar vacío.
4. Construye el zip del bundle:
```
cd nodejs-project/
zip -0 -r /tmp/nodejs-project-new.zip nodejs-project/ \
-x "*.apk" "*/.git/*"
```
5. Empaca + firma la APK siguiendo cambio_apk_repack.txt:
- cp oasis-v0.6.8.apk /tmp/oasis-temp.apk
- zip -d /tmp/oasis-temp.apk "META-INF/*"
- cd /tmp && zip -0 oasis-temp.apk assets/nodejs-project.zip
- zipalign + apksigner sign
6. Verifica la firma: `apksigner verify --verbose`.
7. Genera nombre con fecha:
`oasis-v$VERSION-$(date +%Y%m%d)-pruebas.apk`
8. Borra APKs de pruebas anteriores en /home/sito/
(mantener la base oasis-v0.6.8.apk).
9. Copia la APK a /var/www/0asis.net/testing-app/
10. Actualiza el symlink latest.apk.
11. Escribe builder.md con resumen del build.
12. Notifica Telegram con link de descarga.
Si zipalign o apksigner fallan: NO subas la APK. Solo
notifica el fallo y deja el archivo en /tmp para debug.
Si el build sale > 200MB (anormal): NO subas. Algo se metió
que no debería. Notifica.
```
## EJEMPLOS DE USO
```bash
# Scout manual
claude -p "$(cat /opt/scripts/prompts/scout.md)" \
--allowed-tools "Read,Write,Bash" \
--working-dir /opt/oasis_mobile
# Merger manual (después de revisar scout)
claude -p "$(cat /opt/scripts/prompts/merger.md)" \
--allowed-tools "Read,Write,Edit,Bash" \
--working-dir /opt/oasis_mobile
# Builder manual
claude -p "$(cat /opt/scripts/prompts/builder.md)" \
--allowed-tools "Read,Write,Bash" \
--working-dir /opt/oasis_mobile
```
## TIPS PARA HACER LOS PROMPTS MÁS FIABLES
1. **Prefijo de identidad**: "Eres el agente X" — fija el rol.
2. **Lista numerada**: las pasos en orden ayuda a no saltar.
3. **Reglas negativas explícitas**: "NUNCA modifiques X".
4. **Comprobaciones de éxito**: "Verifica con node --check".
5. **Fallback claro**: "Si no estás seguro, NO procedas".
6. **Output esperado**: "Escribe reporte en formato X".
7. **Notificación**: cada agente notifica al final.
## TAMAÑO DE PROMPTS
Los tres prompts juntos suman ~3000 tokens.
Con context (lectura de CONTEXT/*) + ejecución, cada agente
consume ~30-60k tokens en input + ~5-15k output.
Coste estimado total por sync: ~$0.5-1.50 USD.
```

View file

@ -0,0 +1,295 @@
# Scripts bash listos para usar
Copia a `/opt/scripts/` en el VPS Debian.
## `oasis-scout.sh`
```bash
#!/bin/bash
set -euo pipefail
REPO=/opt/oasis_mobile
REPORTS=/var/oasis-auto/reports
mkdir -p "$REPORTS"
cd "$REPO"
git fetch upstream 2>&1
DATE=$(date +%Y-%m-%d)
claude -p "$(cat /opt/scripts/prompts/scout.md)" \
--allowed-tools "Read,Write,Bash" \
> "$REPORTS/$DATE-scout-claude.log" 2>&1
# El reporte JSON y MD se generan por claude
if [ -f "$REPORTS/$DATE-scout.json" ]; then
bash /opt/scripts/notify-telegram.sh "📊 Scout listo para $DATE. Ver: https://0asis.net/admin/reports/$DATE"
else
bash /opt/scripts/notify-telegram.sh "❌ Scout falló para $DATE. Log: $REPORTS/$DATE-scout-claude.log"
exit 1
fi
```
## `oasis-merger.sh`
```bash
#!/bin/bash
set -euo pipefail
REPO=/opt/oasis_mobile
REPORTS=/var/oasis-auto/reports
DATE=$(date +%Y-%m-%d)
THRESHOLD=${AUTO_APPROVE_THRESHOLD:-1.0}
cd "$REPO"
# Verificar que existe scout reciente
if [ ! -f "$REPORTS/$DATE-scout.json" ]; then
bash /opt/scripts/notify-telegram.sh "⚠️ Merger: no hay scout.json para $DATE. Saltando."
exit 0
fi
# Leer conflict_score
SCORE=$(jq -r '.conflict_score' "$REPORTS/$DATE-scout.json")
APPROVED=$(jq -r '.approved // false' "$REPORTS/$DATE-scout.json")
if [ "$APPROVED" != "true" ] && (( $(echo "$SCORE > $THRESHOLD" | bc -l) )); then
bash /opt/scripts/notify-telegram.sh "⏸ Merger: conflict_score $SCORE > $THRESHOLD, esperando aprobación manual."
exit 0
fi
# Procede con merge
claude -p "$(cat /opt/scripts/prompts/merger.md)" \
--allowed-tools "Read,Write,Edit,Bash" \
> "$REPORTS/$DATE-merger-claude.log" 2>&1
if [ $? -eq 0 ]; then
bash /opt/scripts/notify-telegram.sh "✅ Merger OK para $DATE. Lista para build."
else
bash /opt/scripts/notify-telegram.sh "❌ Merger falló para $DATE."
fi
```
## `oasis-builder.sh`
```bash
#!/bin/bash
set -euo pipefail
REPO=/opt/oasis_mobile
APKS=/var/www/0asis.net/testing-app
DATE=$(date +%Y%m%d)
mkdir -p "$APKS"
cd "$REPO"
# Verificar working tree limpio
if [ -n "$(git status --porcelain)" ]; then
bash /opt/scripts/notify-telegram.sh "⚠️ Builder: working tree no limpio. Saltando."
exit 1
fi
# Verificar no hay markers de conflicto
if grep -rn "<<<<<<< HEAD" "$REPO/nodejs-project/" 2>/dev/null; then
bash /opt/scripts/notify-telegram.sh "❌ Builder: hay conflictos sin resolver."
exit 1
fi
# Build zip
cd "$REPO/nodejs-project"
zip -0 -r /tmp/nodejs-project-new.zip nodejs-project/ \
-x "*.apk" "*/.git/*" > /tmp/zip.log 2>&1
# Build APK
mkdir -p /tmp/assets
cp /tmp/nodejs-project-new.zip /tmp/assets/nodejs-project.zip
cp /opt/oasis-base/oasis-v0.6.8.apk /tmp/oasis-temp.apk
zip -d /tmp/oasis-temp.apk "META-INF/*" >/dev/null
cd /tmp && zip -0 oasis-temp.apk assets/nodejs-project.zip >/dev/null
SDK=/opt/android-sdk/build-tools/35.0.1
$SDK/zipalign -f -p 4 /tmp/oasis-temp.apk /tmp/oasis-aligned.apk
$SDK/apksigner sign \
--ks /opt/secrets/oasis-release-key.jks \
--ks-pass pass:oasis123 \
--key-pass pass:oasis123 \
--ks-key-alias oasis \
/tmp/oasis-aligned.apk
$SDK/apksigner verify /tmp/oasis-aligned.apk || {
bash /opt/scripts/notify-telegram.sh "❌ APK signature inválida."
exit 1
}
# Detectar versión del package.json
VERSION=$(jq -r '.version' "$REPO/nodejs-project/nodejs-project/src/server/package.json")
# Borrar pruebas anteriores y copiar
rm -f "$APKS/oasis-*-pruebas.apk"
NAME="oasis-v$VERSION-$DATE-pruebas.apk"
cp /tmp/oasis-aligned.apk "$APKS/$NAME"
ln -sf "$NAME" "$APKS/latest.apk"
SIZE=$(du -h "$APKS/$NAME" | cut -f1)
bash /opt/scripts/notify-telegram.sh "📱 APK $NAME ($SIZE) lista: https://0asis.net/testing-app/$NAME"
```
## `notify-telegram.sh`
```bash
#!/bin/bash
TOKEN="${TELEGRAM_BOT_TOKEN:-}"
CHAT="${TELEGRAM_CHAT_ID:-}"
MSG="${1:-empty}"
if [ -z "$TOKEN" ] || [ -z "$CHAT" ]; then
echo "Telegram no configurado, mensaje:"
echo "$MSG"
exit 0
fi
curl -s -X POST "https://api.telegram.org/bot$TOKEN/sendMessage" \
-d "chat_id=$CHAT" \
-d "text=$MSG" \
-d "parse_mode=Markdown" > /dev/null
```
## `/etc/cron.d/oasis-auto`
```cron
# Oasis Mobile auto-update pipeline
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxx
TELEGRAM_BOT_TOKEN=123456789:AAxxxx
TELEGRAM_CHAT_ID=-1001234567890
AUTO_APPROVE_THRESHOLD=0.5
0 3 * * 1 oasis /opt/scripts/oasis-scout.sh
0 4 * * 1 oasis /opt/scripts/oasis-merger.sh
0 5 * * 1 oasis /opt/scripts/oasis-builder.sh
```
## Webhook receiver (Python Flask)
```python
# /opt/oasis-webhook/app.py
from flask import Flask, request, abort
import hmac, hashlib, subprocess, os
app = Flask(__name__)
SECRET = os.environ['WEBHOOK_SECRET'].encode()
@app.post("/api/oasis-release")
def release():
sig = request.headers.get("X-Hub-Signature-256", "")
mac = hmac.new(SECRET, request.data, hashlib.sha256)
expected = "sha256=" + mac.hexdigest()
if not hmac.compare_digest(sig, expected):
abort(401)
event = request.headers.get("X-GitHub-Event")
if event != "release":
return "skip", 200
payload = request.json
if payload.get("action") == "published":
tag = payload["release"]["tag_name"]
subprocess.Popen([
"sudo", "-u", "oasis",
"/opt/scripts/oasis-scout.sh",
"--tag", tag, "--reason", "webhook"
])
return "ok", 200
```
## `/etc/systemd/system/oasis-webhook.service`
```ini
[Unit]
Description=Oasis webhook receiver
After=network.target
[Service]
User=oasis
WorkingDirectory=/opt/oasis-webhook
EnvironmentFile=/opt/secrets/webhook.env
ExecStart=/usr/bin/python3 -m gunicorn -b 127.0.0.1:5000 app:app
Restart=always
[Install]
WantedBy=multi-user.target
```
## `/etc/caddy/Caddyfile`
```
0asis.net {
encode gzip zstd
handle /api/oasis-release {
reverse_proxy 127.0.0.1:5000
}
handle_path /testing-app/* {
root * /var/www/0asis.net/testing-app
file_server browse
@apk path *.apk
header @apk Content-Disposition "attachment"
}
handle {
root * /var/www/0asis.net
file_server
try_files {path} {path}/ /index.html
}
}
```
## Setup inicial — `bootstrap.sh`
```bash
#!/bin/bash
# Ejecutar UNA vez al preparar el VPS Debian
set -euo pipefail
# 1. User dedicado
useradd -m -s /bin/bash oasis || true
# 2. Directorios
mkdir -p /opt/oasis_mobile /opt/scripts /opt/secrets /opt/oasis-base
mkdir -p /var/oasis-auto/reports /var/www/0asis.net/testing-app
# 3. Dependencias del sistema
apt update
apt install -y git curl jq bc python3-pip nginx-light \
openjdk-17-jdk-headless zip unzip cron
# 4. Caddy
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/setup.deb.sh' | bash
apt install -y caddy
# 5. Android SDK build-tools
mkdir -p /opt/android-sdk
cd /opt/android-sdk
curl -L -o cmdline-tools.zip \
"https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip"
unzip cmdline-tools.zip
cmdline-tools/bin/sdkmanager --sdk_root=/opt/android-sdk \
"build-tools;35.0.1"
# 6. Claude Code
curl -fsSL https://claude.ai/install.sh | bash
# 7. Permisos
chown -R oasis:oasis /opt/oasis_mobile /var/oasis-auto /opt/scripts
# 8. Clonar repo (necesita SSH key configurada)
sudo -u oasis git clone git@code.03c8.net:s1to/oasis_mobile.git /opt/oasis_mobile
cd /opt/oasis_mobile
sudo -u oasis git remote add upstream https://github.com/epsylon/oasis.git
echo "Bootstrap completo. Configura:"
echo " - /opt/secrets/oasis-release-key.jks (keystore)"
echo " - /etc/cron.d/oasis-auto (con tu ANTHROPIC_API_KEY)"
echo " - DNS de 0asis.net apuntando a este server"
echo " - /etc/caddy/Caddyfile"
echo " - systemctl enable --now oasis-webhook"
```

View file

@ -0,0 +1,258 @@
===============================================================
DEBIAN VPS — Setup paso a paso
===============================================================
REQUISITOS MÍNIMOS DEL VPS
-------------------------
CPU: 2 cores
RAM: 4 GB (mínimo, recomendado 8 GB para AI tasks)
Disco: 30 GB (10 para sistema, 5 para Android SDK,
10 para histórico de APKs)
OS: Debian 12 (bookworm)
Red: IP pública con dominio (si vas a usar webhooks)
PASO 1 — USUARIO Y DIRECTORIOS
------------------------------
sudo adduser --system --group --home /home/oasis oasis
sudo mkdir -p /opt/oasis_mobile /opt/scripts /opt/secrets \
/opt/oasis-base /opt/oasis-webhook \
/var/oasis-auto/reports /var/oasis-auto/apks \
/var/www/0asis.net/testing-app
sudo chown -R oasis:oasis /opt/oasis_mobile /opt/scripts \
/var/oasis-auto /var/www/0asis.net
PASO 2 — DEPENDENCIAS BASE
--------------------------
sudo apt update
sudo apt install -y \
git curl wget jq bc \
python3 python3-pip python3-flask python3-gunicorn \
openjdk-17-jdk-headless \
zip unzip cron \
build-essential
PASO 3 — CADDY (REVERSE PROXY)
------------------------------
sudo apt install -y debian-keyring debian-archive-keyring \
apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | \
sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | \
sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install -y caddy
sudo systemctl enable caddy
PASO 4 — ANDROID SDK BUILD-TOOLS
--------------------------------
cd /tmp
wget https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip
sudo mkdir -p /opt/android-sdk/cmdline-tools
sudo unzip -q commandlinetools-linux-*.zip -d /opt/android-sdk/cmdline-tools
sudo mv /opt/android-sdk/cmdline-tools/cmdline-tools \
/opt/android-sdk/cmdline-tools/latest
sudo yes | /opt/android-sdk/cmdline-tools/latest/bin/sdkmanager --licenses
sudo /opt/android-sdk/cmdline-tools/latest/bin/sdkmanager \
"build-tools;35.0.1"
# Verificar
/opt/android-sdk/build-tools/35.0.1/apksigner version
PASO 5 — CLAUDE CODE CLI
------------------------
# Como usuario oasis (no root):
sudo -u oasis -i
curl -fsSL https://claude.ai/install.sh | bash
# Loguearse o usar API key (recomendado para automatización):
export ANTHROPIC_API_KEY="sk-ant-xxxxx"
# Test
claude -p "say hello" --allowed-tools "" \
--output-format text
exit # vuelve a root
PASO 6 — REPO LOCAL
-------------------
sudo -u oasis git clone <URL del repo oasis_mobile> /opt/oasis_mobile
cd /opt/oasis_mobile
sudo -u oasis git remote add upstream https://github.com/epsylon/oasis.git
sudo -u oasis git fetch upstream
# Verificar
sudo -u oasis git log --oneline upstream/main | head -5
PASO 7 — KEYSTORE
-----------------
# COPIAR el keystore desde tu máquina:
scp ~/oasis-release-key.jks \
oasis@your-vps:/opt/secrets/oasis-release-key.jks
# Permisos restrictivos
sudo chmod 600 /opt/secrets/oasis-release-key.jks
sudo chown oasis:oasis /opt/secrets/oasis-release-key.jks
# Copia también el APK base
scp ~/oasis-v0.6.8.apk \
oasis@your-vps:/opt/oasis-base/oasis-v0.6.8.apk
PASO 8 — SCRIPTS Y PROMPTS
--------------------------
# Copia los scripts de AUTOMATIZACION/09_SCRIPTS.md a:
/opt/scripts/oasis-scout.sh
/opt/scripts/oasis-merger.sh
/opt/scripts/oasis-builder.sh
/opt/scripts/notify-telegram.sh
# Copia los prompts de AUTOMATIZACION/08_PROMPTS_para_agentes.md a:
/opt/scripts/prompts/scout.md
/opt/scripts/prompts/merger.md
/opt/scripts/prompts/builder.md
# Permisos
sudo chmod +x /opt/scripts/*.sh
sudo chown -R oasis:oasis /opt/scripts
PASO 9 — TELEGRAM BOT (opcional)
-------------------------------
# En Telegram: hablar con @BotFather, crear bot, copiar token.
# Añadir el bot a un canal/grupo donde recibir notificaciones.
# Obtener chat_id con:
curl "https://api.telegram.org/bot$TOKEN/getUpdates"
# Guardar en /opt/secrets/telegram.env:
TELEGRAM_BOT_TOKEN=123456789:AAxxxx
TELEGRAM_CHAT_ID=-1001234567890
sudo chmod 600 /opt/secrets/telegram.env
PASO 10 — CRON
--------------
sudo cp /opt/scripts/oasis-auto.cron /etc/cron.d/oasis-auto
# Verificar
systemctl restart cron
cat /etc/cron.d/oasis-auto
PASO 11 — WEBHOOK (opcional, para opción D)
-------------------------------------------
cd /opt/oasis-webhook
# Copia app.py de 09_SCRIPTS.md
# Generar secret
python3 -c "import secrets; print(secrets.token_hex(32))" \
| sudo tee /opt/secrets/webhook-secret
# Service
sudo cp oasis-webhook.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now oasis-webhook
# Verificar
curl http://127.0.0.1:5000/api/health
PASO 12 — DNS Y HTTPS
---------------------
# En tu DNS provider:
A 0asis.net -> IP-DEL-VPS
# Caddyfile:
sudo cp Caddyfile /etc/caddy/Caddyfile
sudo systemctl reload caddy
# Caddy obtiene certificado Let's Encrypt automáticamente.
# Verificar:
curl -I https://0asis.net
PASO 13 — WEBHOOK EN GITHUB
---------------------------
# En el fork de oasis_mobile en GitHub:
Settings → Webhooks → Add webhook
URL: https://0asis.net/api/oasis-release
Secret: el de /opt/secrets/webhook-secret
Events: only "Releases"
PASO 14 — TEST INICIAL
----------------------
# Como oasis user:
sudo -u oasis -i
# Forzar scout manualmente
/opt/scripts/oasis-scout.sh
# Verificar reporte
ls /var/oasis-auto/reports/
# Si OK, esperar al lunes o forzar pipeline completo
/opt/scripts/oasis-merger.sh && /opt/scripts/oasis-builder.sh
CHECKLIST FINAL
---------------
[ ] User oasis creado
[ ] /opt/oasis_mobile con remote upstream
[ ] /opt/secrets con keystore y permisos 600
[ ] /opt/oasis-base con oasis-v0.6.8.apk
[ ] Android SDK build-tools instalado
[ ] Claude Code instalado con API key
[ ] Scripts en /opt/scripts/ con permisos
[ ] Cron /etc/cron.d/oasis-auto configurado
[ ] Telegram bot (opcional)
[ ] Caddy + HTTPS para 0asis.net
[ ] Webhook receiver en systemd (opcional)
[ ] Webhook en GitHub configurado (opcional)
[ ] Test inicial OK
MONITORING
----------
# Logs cron
tail -f /var/log/syslog | grep CRON
# Logs de cada agente
tail -f /var/oasis-auto/reports/*.log
# Logs Caddy
journalctl -u caddy -f
# Logs webhook
journalctl -u oasis-webhook -f
# Espacio en disco
df -h /var/www /opt /var/oasis-auto
PROBLEMAS COMUNES
-----------------
"claude command not found":
El PATH del cron no incluye ~/.local/bin
→ en cron usa /home/oasis/.local/bin/claude full path
"git push falla":
El user oasis necesita SSH key configurada
→ ssh-keygen -t ed25519 y añadir a tu Gitea/GitHub
"apksigner: java not found":
sudo apt install openjdk-17-jdk-headless
Verifica: java --version
"permission denied en keystore":
sudo chown oasis:oasis /opt/secrets/oasis-release-key.jks
sudo chmod 600 ...