PROYECTO 3.4

🐳 Proyecto 4: tercer ejecutor

Hasta aquí el curso habló de dos runtimes. Pero ya existe un tercero corriendo en tu máquina desde hace semanas: el dsh-sandbox, el agente de DeepSeek en contenedor, con modelo local o remoto. Tiene tres skills copiadas a mano (drift garantizado) y ninguna capa de contexto. Este proyecto agrega un destino --dsh a la fuente canónica de skills, le da al dsh un prime que le indica leer los archivos correctos, y hace el readback allí dentro — sin juntar nunca ~/projetos con un proveedor remoto.

6
Temas
~50
Minutos
Avanzado
Nivel
Proyecto
Tipo

🎯 El proyecto en una pantalla

ObjetivoProbar que el núcleo portátil sirve para un tercer ejecutor — el dsh-sandbox — y que sus skills salen de la misma fuente canónica que Claude y Codex, sin copia manual.
Terminas conUn sync-skills.sh con destino --dsh y drift check, una skill prime en ~/projetos/dsh-skills, y un readback ejecutado en el panel con modelo local y comparado con el remoto.
Criterio de aceptaciónDrift cero en los tres destinos; el dsh cita AGENTS.md, context/, tasks/current.md y handoffs/latest.md por su nombre; y ningún paso usó remoto-projetos.
1

🐳 Qué es el dsh-sandbox

El dsh-sandbox es @deepseek-ai/dsh en la versión 0.1.1-rc.1 corriendo en Docker, con panel en 127.0.0.1:9080 y contenedor dsh-orchestrator-runtime-1. La versión está congelada dentro de work/node_modules a propósito: un arranque no vuelve al registry, y actualizar es un acto explícito. Todo el control pasa por un único script en la raíz del proyecto — ./dsh — con cinco verbos.

Lo que importa para este curso es el diseño de los modos. No existe "encender todo": el montaje de disco y el proveedor de modelo están atados. En el modo local, ~/projetos se monta dentro del contenedor y el único proveedor es Ollama en la propia máquina — tus archivos están ahí, pero no sale ni un byte. En el modo remoto, el proveedor es OpenRouter y ~/projetos no se monta — el modelo es mejor, pero no ve nada tuyo. La combinación de ambos existe (remoto-projetos) y pide escribir la palabra CONFIRMO, porque es exactamente la combinación peligrosa.

contenedor dsh dsh-orchestrator-runtime-1 panel 127.0.0.1:9080 ./dsh local ~/projetos MONTADO proveedor: solo Ollama (en la máquina) tus archivos entran, nada sale ./dsh remoto ~/projetos FUERA proveedor: OpenRouter (internet) mejor modelo, sin ver tus archivos skills montadas ~/projetos/dsh-skills → /work/.dsh/skills ./dsh remoto-projetos montaje + proveedor remoto 269 archivos de secretos en riesgo exige escribir CONFIRMO nunca para readback

Lee el diagrama siguiendo las flechas que entran al contenedor. Local trae tus archivos pero ata el modelo a la máquina; remoto libera el modelo pero deja los archivos afuera. El bloque rojo es la única combinación que junta ambos, y existe justamente para que sea difícil activarla por accidente.

Objetivo: levantar dsh en el modo correcto y confirmar que el panel responde antes que cualquier otra cosa.

cd ~/projetos/dsh-sandbox

# ver en qué estado está ahora (puede llevar días en ejecución)
./dsh status

# para este proyecto: modo local (projetos montados + solo Ollama)
./dsh local

# el panel solo escucha en loopback; desde fuera, usa un túnel SSH
curl -sf -o /dev/null -w '%{http_code}\n' http://127.0.0.1:9080
# esperado: 200

# contenedor y límite de memoria
docker ps --filter name=dsh-orchestrator-runtime-1

# al terminar
./dsh off

Cómo verificar: ./dsh status indica el modo activo y el curl devuelve 200. Si necesitas acceder desde otra máquina, el camino es ssh -L 9080:127.0.0.1:9080 …: dsh rechaza el bind en 0.0.0.0 por decisión de los autores, y la app no tiene ninguna autenticación.

El contenedor no es el costo: pesa unos 85 MB en reposo, con un límite de 3 GB. El peso real es el modelo cargado en el host, sin límite: de 17 GB a 45 GB según lo que elijas. Ese es el número que decide si la máquina aguanta, no Docker.

Conceptos clave

Tercer ejecutor

Un consumidor más del mismo contexto portátil, junto a Claude y Codex.

Modos vinculados

Montaje y proveedor se deciden juntos, nunca por separado.

Versión congelada

0.1.1-rc.1 instalada localmente; el arranque no busca actualizaciones.

Solo loopback

El panel no tiene login; acceso remoto solo por túnel SSH.

2

🧬 Copiar a mano es drift garantizado

Hoy dsh tiene tres skills, y las tres llegaron ahí con cp: formato-curso-v2, formato-curso-v5 y capa-inema (dependencia de las dos primeras). Viven en ~/projetos/dsh-skills, montado en el contenedor como /work/.dsh/skills. El formato es compatible (es el mismo SKILL.md de Claude) y por eso la copia funciona. El problema no es que no funcione hoy; es que no siga igual mañana.

Llámalo drift: corriges un bug en la skill de Claude, pruebas, publicas, y la copia de dsh se queda en la versión anterior. Nada se rompe de forma ruidosa. dsh simplemente genera un curso con el patrón de hace dos meses y lo descubres en el output. El diagnóstico es claro sobre la escala del problema: ya son cuatro consumidores de skills, no dos: Claude (117), Codex (27), dsh (3 copias manuales) y openpcbotv3 (16 propias). Sin una fuente canónica, cada uno diverge por su cuenta, y la divergencia crece con el tiempo.

fuente canónica skills/<nombre>/ (polyskill) un lugar, una verdad build dist/<runtime>/ ~/.claude/skills117 skills ~/.codex/skills27 skills ~/projetos/dsh-skills 3 copias a mano → ESTE PROYECTO openpcbotv3/skills destino --v3, queda para después drift compara cada destino con la salida del build meta: cero

Una fuente canónica a la izquierda, un build en el medio, cuatro destinos a la derecha. Los dos primeros ya salen del build; el tercero (dsh) es lo que este proyecto agrega; el cuarto queda para después. La caja de la derecha es lo que convierte esto en una garantía: sin drift, tienes cuatro copias y ninguna prueba de que son iguales.

✓ Skill generada por el build

  • Corregiste en la fuente: un build y un install actualizan todos los destinos.
  • El drift lo detecta antes de que lo detecte el usuario.
  • Respaldo automático del destino anterior en cada instalación.
  • Una sola revisión sirve a los cuatro consumidores.

✗ Skill copiada a mano

  • Nadie recuerda cuál copia es la más reciente.
  • La divergencia aparece en el output, meses después, y parece un bug del modelo.
  • Corregir se vuelve cuatro ediciones, y olvidas una.
  • Sin verificador, "está sincronizado" es fe, no un hecho.

Cuidado con el nombre de la carpeta: el destino es ~/projetos/dsh-skills, y no ~/projetos/skills — este último ya es el repositorio git inematds/skills del curso de Agent Skills. Copiar al nombre equivocado contamina un repo publicado. Verifica la ruta antes de ejecutar cualquier cp -a.

Conceptos clave

Drift

Copias que empiezan iguales y divergen sin que nadie lo note.

Fuente canónica

El único lugar que se edita; todo lo demás se genera.

Cuatro consumidores

Claude, Codex, dsh y openpcbotv3 — todos queriendo la misma skill.

Falla silenciosa

El drift no genera error; genera un resultado equivocado con apariencia de correcto.

3

🔧 Agregar el destino --dsh a sync-skills.sh

El scripts/sync-skills.sh que ya usaste en la Trilha 2 tiene cuatro verbos: import, build, drift e install. Asume dos runtimes todo el tiempo, con el bucle for rt in claude codex y la ruta $HOME/.$rt/skills/$s — un truco elegante que funciona porque las dos carpetas tienen el mismo formato de nombre. El dsh rompe ese patrón: su destino es ~/projetos/dsh-skills/<nome>, que no encaja en la fórmula.

La buena noticia es que el dsh acepta el mismo SKILL.md de Claude. Así que no hace falta un nuevo objetivo de polyskill build: lo que se copia al dsh es el dist/claude/<nome> que el build ya produce. El cambio es pequeño y quirúrgico — una función que resuelve la ruta de destino por runtime, el caso --dsh en el install, y la inclusión del dsh en el bucle del drift, que es la parte que realmente vale la pena.

Objetivo: aplicar el patch que agrega el tercer destino, manteniendo el drift como verificación de los tres.

# --- en scripts/sync-skills.sh, justo después del `mkdir -p skills dist` ---

# resuelve la carpeta de destino de cada runtime (dsh se sale del patrón ~/.<rt>/skills)
dest_for() {
  case "$1" in
    claude|codex) printf '%s/.%s/skills/%s\n' "$HOME" "$1" "$2" ;;
    dsh)          printf '%s/projetos/dsh-skills/%s\n' "$HOME" "$2" ;;
    *) return 1 ;;
  esac
}
# el dsh consume el MISMO formato de Claude: el origen es dist/claude
src_for() {
  case "$1" in dsh) echo claude ;; *) echo "$1" ;; esac
}

# --- en el verbo `drift`: cambiar `for rt in claude codex` por: ---
      for rt in claude codex dsh; do
        out="$d/dist/$(src_for "$rt")/$s"; tgt="$(dest_for "$rt" "$s")"
        [ -d "$out" ] && [ -d "$tgt" ] || { echo "[no instalada] $s → $rt"; continue; }
        if diff -rq "$out" "$tgt" >/dev/null; then echo "[ok] $s → $rt"; else echo "[DRIFT] $s → $rt"; rc=1; fi
      done

# --- en el verbo `install`: cambiar `for rt in claude codex` por: ---
    for rt in claude codex dsh; do
      case "$tgt" in --both) [ "$rt" = dsh ] && continue ;; --all) ;; --$rt) ;; *) continue ;; esac
      out="skills/$s/dist/$(src_for "$rt")/$s"; [ -d "$out" ] || { echo "ejecuta build antes: $out"; exit 1; }
      dest="$(dest_for "$rt" "$s")"
      [ -e "$dest" ] && cp -a "$dest" "$(dirname "$dest")/.$s.bak-$(date +%s)"
      mkdir -p "$(dirname "$dest")"; cp -a "$out" "$dest"; echo "instalada: $dest"
      # preservado del original: Codex también descubre en ~/.agents/skills
      [ "$rt" = codex ] && [ -d "$HOME/.agents/skills" ] && cp -a "$out" "$HOME/.agents/skills/$s" && echo "reflejada: ~/.agents/skills/$s"
    done

Cómo verificar: bash -n scripts/sync-skills.sh pasa sin error de sintaxis, y scripts/sync-skills.sh drift pasa a imprimir tres líneas por skill en lugar de dos — la tercera terminando en → dsh.

Objetivo: traer las tres skills copiadas a mano al flujo canónico y dejar el drift en cero.

cd ~/projetos/agente-claude-codex

# 1. guardar las copias actuales antes de sobrescribir (son el último estado bueno conocido)
cp -a ~/projetos/dsh-skills ~/projetos/dsh-skills.bak-$(date +%Y%m%d)

# 2. importar a la fuente canónica (a partir del original de Claude)
scripts/sync-skills.sh import formato-curso-v2 formato-curso-v5 capa-inema
scripts/sync-skills.sh build

# 3. instalar ahora también en el dsh
for s in formato-curso-v2 formato-curso-v5 capa-inema; do
  scripts/sync-skills.sh install "$s" --dsh
done

# 4. la prueba
scripts/sync-skills.sh drift; echo "rc=$?"
# esperado: solo líneas [ok], rc=0

Cómo verificar: rc=0 y ninguna línea [DRIFT]. Si aparece drift justo después del install, la copia a mano tenía alguna edición local que nunca volvió a la fuente — compara con el respaldo del paso 1 y lleva la diferencia a skills/<nome>/ antes de continuar.

Por qué --both sigue significando dos: el patch mantiene --both como Claude+Codex e introduce --all para los tres. Quien ya tiene la costumbre de escribir --both no se lleva la sorpresa de una instalación en un lugar nuevo: cambiar el comportamiento de un flag existente es el tipo de trampa que solo aparece tres semanas después.

Conceptos clave

Destino fuera del estándar

El dsh no vive en ~/.<runtime>/skills; necesita un resolvedor.

Reúso de dist/claude

Formato compatible: no hace falta ningún target de build nuevo.

Drift como contrato

Un destino que no entra en el drift no está realmente en el flujo.

Flag estable

Agregar --all en lugar de cambiar lo que hace --both.

4

🧭 Darle contexto al dsh: la skill de prime

Con las skills resueltas, falta el contexto. El dsh escanea $DSH_HOME/skills y nada más: no tiene auto-load de AGENTS.md ni de CLAUDE.md. Si abres el panel dentro de un proyecto migrado, ve los archivos (en modo local) pero no sabe que debería abrirlos. Como no hay hook, no hay evento de apertura ni instrucción global, la única palanca disponible es la que ya usa: una skill.

De ahí la skill de prime. No hace nada más que pedir la lectura, en el orden correcto: AGENTS.md, luego context/, luego tasks/current.md, luego handoffs/latest.md, el mismo orden que Claude y Codex siguen por instrucción. Es la misma idea del tema 5 del Proyecto 2: cuando el evento no existe, el comportamiento se convierte en lectura pedida explícitamente. Y como el dsh acepta el formato de Claude, esta skill sale de la misma fuente canónica y va a los tres destinos.

1

Escribir el prime en la fuente canónica

Un SKILL.md corto en skills/prime/, con el orden de lectura y el formato de la respuesta.

2

Build e install en los tres destinos

install prime --all lleva la misma skill a Claude, Codex y dsh.

3

Levantar el dsh en modo local

Sin ~/projetos montado no hay nada que leer; el readback tiene que hacerse en modo local.

4

Hacer las 5 preguntas en el panel

Las mismas del readback de la Ruta 2. El criterio es citar el archivo, no la belleza de la respuesta.

Objetivo: crear la skill de prime e instalarla en los tres destinos, incluido el dsh.

cd ~/projetos/agente-claude-codex
mkdir -p skills/prime

cat > skills/prime/SKILL.md <<'MD'
---
name: prime
description: Carga el contexto del proyecto antes de cualquier trabajo. Úsala al
  comienzo de toda sesión, antes de la primera edición, y siempre que pierdas el hilo.
---

# Prime — lee antes de actuar

Lee, en este orden, y solo entonces responde:

1. `AGENTS.md` en la raíz del proyecto — las reglas estables.
2. `context/overview.md` — los hechos verificados. Si existe
   `context/decisions/`, lee también la decisión más reciente.
3. `tasks/current.md` — lo que está en curso ahora.
4. `handoffs/latest.md` — lo que hizo la última sesión y cuál es la próxima acción.

Si alguno de estos archivos no existe, di cuál falta en lugar de inventar.

Cierra el prime con cuatro líneas, cada una citando el archivo de donde vino:

- **Proyecto:** qué es, en una frase.
- **Estado:** qué está listo y qué está pendiente.
- **Próxima acción:** la frase exacta escrita en `handoffs/latest.md`.
- **Regla que más importa aquí:** la restricción de `AGENTS.md` que
  más afecta a la próxima acción.
MD

scripts/sync-skills.sh build
scripts/sync-skills.sh install prime --all
ls ~/projetos/dsh-skills/prime/SKILL.md

Cómo verificar: el ls encuentra el archivo, y scripts/sync-skills.sh drift muestra [ok] prime → dsh junto con claude y codex. Luego, en el panel en 127.0.0.1:9080 con el dsh en modo local, pide "usa la skill prime en el proyecto /projetos/<tu-piloto>" y comprueba que las cuatro líneas vuelvan con el nombre de archivo en cada una.

Atención a los puentes de ruta: dentro del contenedor, ~/projetos aparece como /projetos y las skills se ven en /work/.dsh/skills. Hay dos symlinks en work/ justamente para que los ~/... escritos en las skills se resuelvan allí dentro; aparecen rotos cuando los miras desde el host, y eso es lo esperado. Al pedir algo desde el panel, usa la ruta de adentro.

Conceptos clave

Prime

La skill que reemplaza el auto-load inexistente por lectura pedida.

Orden de lectura

AGENTS → context → tasks/current → handoffs/latest, siempre igual.

Puente de ruta

Symlinks en work/ que hacen que ~/… se resuelva dentro del contenedor.

Citar la fuente

Una respuesta sin nombre de archivo no cuenta como lectura comprobada.

5

🔒 Seguridad: 269 secretos y la regla que no se negocia

La auditoría contó 269 archivos de secretos dentro de ~/projetos, entre ellos los dos .env que todo el curso trata como fuente única de API keys: wifi/.env y openpcbotv2/.env. Montar ese árbol en un contenedor cuyo proveedor de modelo es remoto significa darle a un servicio de terceros la posibilidad de leer cualquiera de ellos, porque el agente decide por su cuenta qué archivos abrir. No existe el "no va a mirar": la única garantía es la que está en el diseño.

Por eso montaje y proveedor van atados. La decisión se tomó una sola vez, en el script, y no en cada sesión: local da acceso a los archivos y mantiene el modelo dentro de la máquina; remoto libera el modelo y saca los archivos de escena. La tercera opción existe y pide escribir CONFIRMO, y la regla de este proyecto es corta: nunca uses remoto-projetos para readback. El readback es justamente el ejercicio de pedirle a un agente que lea archivos de tu disco; es el peor momento posible para tener un proveedor externo en la línea.

✓ Combinaciones permitidas

  • local para readback y para generar cursos: archivos dentro, modelo dentro.
  • remoto para comparar la calidad de la prosa con contenido pegado a mano.
  • Panel solo en 127.0.0.1; desde afuera, únicamente por túnel SSH.
  • ./dsh off al terminar, para no dejar un montaje activo sin necesidad.

✗ Nunca

  • remoto-projetos para readback: junta los 269 secretos con un proveedor externo.
  • Exponer el panel con --host 0.0.0.0: la app no tiene ninguna autenticación.
  • Copiar un .env dentro de dsh-skills "para que la skill lo encuentre".
  • Escribir CONFIRMO en automático: la fricción existe para que te detengas a pensar.

Objetivo: confirmar, antes de ejecutar el readback, que el modo activo es el seguro, y medir el tamaño de la superficie.

cd ~/projetos/dsh-sandbox

# cuántos archivos de secretos expondría el montaje (solo el conteo, nunca el contenido)
find ~/projetos -maxdepth 3 \( -name '.env' -o -name '.env.*' -o -name '*credential*' \) \
  -type f 2>/dev/null | wc -l

# el modo activo, antes de pedirle cualquier cosa al panel
./dsh status

# verificación directa: ¿existe el montaje de /projetos en este contenedor?
docker inspect dsh-orchestrator-runtime-1 \
  | python3 -c 'import json,sys; [print(m["Source"], "->", m["Destination"]) for m in json.load(sys.stdin)[0]["Mounts"]]'

# el panel no puede estar escuchando fuera del loopback
ss -ltnp 2>/dev/null | grep 9080
# esperado: 127.0.0.1:9080 — si aparece 0.0.0.0:9080, apágalo YA con ./dsh off

Cómo verificar: si status dice local, inspect muestra /projetos montado y ss muestra solo 127.0.0.1, puedes seguir. Cualquier combinación distinta es motivo para detenerte y corregir antes de escribir la primera pregunta en el panel.

Sobre network_mode: host: el contenedor corre sin aislamiento de red porque dsh solo acepta bind en 127.0.0.1 y, con bridge, el proxy de Docker no alcanza el loopback interno. La consecuencia es que ve todos los servicios de loopback del host: Ollama en 11434, iccmonit en 9003 y lo que esté en marcha. No es un detalle cosmético: elimina la sensación de "está aislado porque es un contenedor". El aislamiento real aquí viene de los modos, no de la red.

Conceptos clave

Montaje atado

Quien ve los archivos no habla con un proveedor externo, y viceversa.

269 secretos

La superficie medida de ~/projetos; el número que justifica la regla.

Fricción intencional

Escribir CONFIRMO existe para impedir el accidente, no el uso.

Contenedor ≠ aislamiento

Con network_mode: host, toda la red del host queda visible.

6

📉 Expectativa honesta: lo que entrega el modelo local

El modelo local de esta máquina es qwen3.8:27b, unos 18 GB cargados en el host, sin límite. Compite por RAM con inemavox, y el historial de caídas por OOM está registrado en el monitoreo; no es una hipótesis. Si vas a ejecutar readback en dsh, haz el preflight: revisa la memoria libre antes y no dejes una síntesis de voz pesada en curso.

Sobre la calidad, el mensaje del diagnóstico es directo: las skills se escribieron para el comportamiento de Claude, y con un modelo local el resultado se queda corto. Pero "se queda corto" hay que medirlo en el eje correcto. Lo que este proyecto prueba es la portabilidad de contexto, y el criterio es citar los archivos correctos. Una prosa más pobre, una estructura más floja y menos matices son límites del modelo. Confundir ambas cosas lleva a la conclusión equivocada: "la portabilidad falló", cuando lo que falló fue la expectativa sobre la calidad de la redacción.

🧪 La prueba que separa el modelo de la portabilidad

Ejecuta la misma pregunta en los dos modos. En remoto, dsh no ve ~/projetos, así que pega el contenido de los archivos en la propia pregunta. Si la respuesta mejora mucho, el cuello de botella era el modelo; si sigue sin citar ningún archivo, ahí sí el problema es tu capa de contexto.

EjeCriterioConclusión si falla
PortabilidadCita AGENTS.md, tasks/current.md, handoffs/latest.md por su nombreFalta el prime, el montaje o los archivos
FidelidadLa próxima acción coincide con la escrita en el handoffLeyó por encima; acorta los archivos
Calidad de la prosaTexto organizado y sin repeticionesLímite del modelo: no invalida nada
EstabilidadTerminó sin OOMInfra: modelo demasiado grande para la RAM libre

Objetivo: hacer el preflight de memoria y registrar el resultado del readback en los dos modos, sin sacar conclusiones apresuradas.

# preflight: ¿cabe ahora el modelo de ~18 GB?
free -g | awk '/Mem:/ {print "livre:", $7, "GB"}'
# regla práctica: con menos de 24 GB libres, no levantes el 27b junto con inemavox

# quién ya está ocupando memoria
ps -eo rss,comm --sort=-rss | head -5 | awk '{printf "%6.1f GB  %s\n", $1/1048576, $2}'

# modelos cargados en Ollama en este momento
ollama ps

# después del readback, registra el resultado junto a los otros dos runtimes
cd ~/projetos/<seu-piloto>
mkdir -p relatorios
$EDITOR relatorios/readback-dsh-local.md    # qué archivos se citaron y la próxima acción que leyó
$EDITOR relatorios/readback-dsh-remoto.md   # misma pregunta, contexto pegado a mano

Cómo verificar: los dos informes existen y el veredicto está escrito en una frase: "citó los cuatro archivos, prosa inferior a Claude" es aprobación; "no citó ningún archivo en los dos modos" es reprobación de la capa de contexto, y entonces el problema está en el prime o en el montaje, no en el modelo.

Criterios de aceptación (marca con evidencia)

  • sync-skills.sh drift devuelve rc=0 con los tres destinos listados. Evidencia: salida del comando.
  • Las 3 skills que antes se copiaban a mano ahora las genera el build. Evidencia: [ok] … → dsh para cada una.
  • La skill prime existe en los tres destinos. Evidencia: ls en las tres rutas.
  • El readback en dsh cita los cuatro archivos por su nombre. Evidencia: relatorios/readback-dsh-local.md.
  • Ningún paso usó remoto-projetos. Evidencia: ./dsh status registrado antes de cada ronda.
  • Ningún OOM durante el ejercicio. Evidencia: el preflight anotado y el inemavox detenido o intacto.

⚠️ Riesgos de este proyecto

  • OOM: el modelo de ~18 GB arranca sin tope y compite con el inemavox por la misma RAM.
  • Usar remoto-projetos por comodidad y exponer los 269 secretos.
  • Copiar a ~/projetos/skills en lugar de dsh-skills y contaminar un repo publicado.
  • Que el install --dsh sobrescriba una copia con una edición local que nunca volvió a la fuente.
  • Concluir "la portabilidad falló" mirando la calidad de la prosa en lugar de las citas.

↩️ Rollback en un comando

  • Skills de dsh: rm -rf ~/projetos/dsh-skills && mv ~/projetos/dsh-skills.bak-AAAAMMDD ~/projetos/dsh-skills.
  • Script: git checkout -- scripts/sync-skills.sh deshace el patch completo.
  • Prime: rm -rf skills/prime en la fuente y en los destinos; nada más depende de ella.
  • Contenedor: ./dsh off apaga todo y desmonta; Claude y Codex siguen intactos.
  • Memoria: ollama stop qwen3.8:27b libera los ~18 GB al instante.

Conceptos clave

Preflight de RAM

Medir la memoria libre antes de arrancar el modelo, no después del bloqueo.

Criterio correcto

Citar los archivos correctos; la calidad de la prosa es otro eje.

Comparar en remoto

Antes de culpar a la portabilidad, prueba con un modelo mejor.

Ejecutor de segunda línea

El dsh no reemplaza a Claude ni a Codex; demuestra que el contexto viaja.

Autoevaluación (opcional): en el readback del dsh en modo local, el modelo citó AGENTS.md, tasks/current.md y handoffs/latest.md, pero el texto quedó repetitivo y mal organizado. ¿Qué concluyes?

🎯 Resumen del proyecto

Tercer ejecutor real — el dsh ya corre en contenedor, con panel en 127.0.0.1:9080 y modos local y remoto que atan montaje y proveedor.
Fin de la copia a mano — destino --dsh en sync-skills.sh, con las tres skills entrando al drift check junto con Claude y Codex.
Contexto por skill — sin auto-load y sin hook, el prime ordena leer AGENTS.md, context/, tasks/current.md y handoffs/latest.md.
Seguridad y expectativa — nunca remoto-projetos para readback; y el criterio es citar los archivos correctos, no la belleza de la prosa.

Próximo proyecto:

3.5 — Workspace de cliente: Venn, alcance y canarios