matapan

Proporciona acceso API con alcance a ChatGPT o Claude a tu repositorio a través de un contenedor Docker. Aislado por defecto, los cambios no afectan tu repositorio a menos que lo permitas.

Documentación

Matapan

Matapan es un plano de control transaccional local-first para código producido por agentes. Los agentes de codificación (ChatGPT, Claude, Codex) obtienen espacios de trabajo desechables y aislados por contenedores, y devuelven trabajo solo como propuestas inmutables con evidencia, aplicadas mediante compare-and-swap. Tu checkout activo nunca está en la ruta de escritura del agente.

El bucle:

importar fuente confiable → espacio de trabajo aislado desechable → herramientas/entorno de ejecución con alcance → capturar ediciones + verificación → sellar propuesta inmutable contra una base esperada → revisión → aplicar compare-and-swap → revocar y destruir → queda un rastro de auditoría redactado.

Matapan es un gestor de transacciones de espacios de trabajo — no un IDE, no un agente, no una caja de arena genérica, no una GUI de Git.

Estado

0.1.0-beta.1 — los ocho sprints planificados están completados: núcleo de seguridad, ciclo de vida del espacio de trabajo (arrendamientos + GC), entorno de ejecución endurecido (gVisor experimental), superficie de herramientas MCP, motor de propuestas MVP, perfiles de política, corredor de secretos, proxy de salida, retención de auditoría, límite del adaptador Charon, empaquetado y endurecimiento adversarial (fuzz + matriz de bordes). Ver CHANGELOG.md, docs/MVP-acceptance.md y docs/docker-limitations.md.

Inicio rápido

Desde cero, en macOS o Linux (requiere git, Go 1.25.12+ para compilar desde el código fuente, y un daemon Docker local para workspace_run):

# Install (builds and installs to /usr/local/bin, or --user for ~/.local/bin)
scripts/install.sh

# Verify the environment
matapan doctor
# git                    ok   git version 2.50.1
# config                 ok   ~/.matapan/config.json
# database               ok   ~/.matapan/matapan.db (schema v7)
# obol key               ok   ~/.matapan/obol.key (perms 600)
# docker                 ok   daemon reachable
# runtime image          ok   present, digest matches
# runtime spawn          ok   hardened container ran, exit 0

# Pre-pull the digest-pinned runtime image
matapan runtime pull

# Create a workspace from a git repo (worktree at an exact commit)
matapan workspace create --repo ~/src/my-app --base main
# {"ID": "019f…", "State": "ready", "Branch": "matapan/019f…", …}

# Start the daemon, then connect an agent (see docs/quickstart-claude.md)
matapand &

El agente luego dirige workspace_file_edit / workspace_run / workspace_commit contra ese ID de espacio de trabajo. Cuando el trabajo está hecho:

# Seal the workspace into an immutable proposal (via the agent or MCP),
# then review and apply with compare-and-swap:
matapan proposal list
matapan proposal show <id>            # diff, digests, evidence, lineage
matapan proposal apply <id> --expected-base <commit>
# {"ProposalID": "019f…", "AppliedHead": "7f84…", "Strategy": "auto",
#  "Rollback": "git -C ~/src/my-app reset --hard <commit>"}

# Housekeeping
matapan workspace destroy <id>        # verified teardown
matapan gc --dry-run                  # what idle/expired GC would collect

Otros tipos de fuente: --source snapshot --path /dir (copia defendida de un directorio no Git), --source fresh [--git-init] (andamiaje vacío). Banderas útiles: --profile restricted (perfil de política), --lease 24h (expiración de GC), --egress proxy.example.com (concesión de salida humana).

Conectando agentes

  • Claude Code / agentes locales (stdio): matapand --stdio con MATAPAN_OBOL configurado — ver docs/quickstart-claude.md.
  • ChatGPT (túnel HTTPS): StreamableHTTP autenticado en /mcp a través de un túnel gestionado por el usuario — ver docs/quickstart-chatgpt.md.

Superficie de herramientas

  • Perfiles (mcp.tool_profile en config.json, predeterminado minimal): minimal es el núcleo de 12 herramientas; full agrega workspace_file_glob y workspace_file_grep tipados para hosts que prefieren búsqueda tipada sobre rg/find de shell (paridad DevSpace).
  • Descubrimiento de capacidades: matapan_capabilities devuelve la versión del servidor, perfil, herramientas + anotaciones, límites duros y banderas de características para que cualquier agente pueda autoconfigurarse.
  • Errores tipados: las fallas de herramientas devuelven un campo {"error": {"code", "message"}} estructurado con códigos estables (unauthorized, not_found, path_escape, workspace_locked, stale_base, spec_refused, state_conflict, invalid_argument, egress_denied, unsupported, unavailable, internal).
  • Instrucciones: AGENTS.md/CLAUDE.md raíz se descubren y devuelven en workspace_status, y sus resúmenes se registran en cada sello de propuesta. El contenido de las instrucciones es datos para el agente, nunca entrada de control — no puede cambiar política, alcances o límites.
  • Concesiones de salida: la red permanece none a menos que el espacio de trabajo tenga una concesión de un humano (matapan workspace create --egress DOMAIN o la herramienta workspace_grant_egress, alcance workspace.grant — los principales de agente no la obtienen). Las ejecuciones concedidas pasan por el proxy de salida de matapan (proxy CONNECT/HTTP de lista blanca): HTTP(S) a dominios concedidos funciona, todo lo demás se deniega y se registra. Honestidad de cumplimiento: en Docker nativo de Linux, el contenedor se adjunta a una red interna sin ruta directa de salida (cumplimiento total); en Docker Desktop, el contenedor se ejecuta en el puente predeterminado con el proxy como su única ruta configurada — HTTP(S) se filtra, pero la salida de IP cruda es una brecha documentada hasta que el proxy sidecar llegue.

Perfiles de política, secretos e identidad

  • Perfiles de política (default, restricted, open; matapan policy list/show): listas blancas de imágenes, política de salida, listas negras de comandos argv[0], techos de recursos. Asignados por espacio de trabajo al crear (--profile); el resumen del perfil se sella en cada propuesta como policy_digest.
  • Secretos: matapan secret set almacena valores cifrados con AES-256-GCM (clave en 0600, nunca texto plano en reposo; valor leído de stdin o --env, nunca argv). Los humanos conceden secretos a los espacios de trabajo (workspace_grant_secret / matapan secret grant); las ejecuciones inyectan solo secretos concedidos como variables de entorno MATAPAN_SECRET_<NAME>; las concesiones se revocan automáticamente al sellar la propuesta y destruir el espacio de trabajo. Los valores se registran con el redactor de ledger en el momento de la inyección.
  • Modo Charon: auth.mode: charon + auth.charon_url cambia la validación de tokens al endpoint de validación de Charon (5s, fail-closed, audiencia matapan aplicada de cualquier manera). review.prevent_self_approval (predeterminado true en modo charon) bloquea al creador de una propuesta de aplicarla o rechazarla — revisión independiente.
  • Modo OAuth: auth.mode: oauth convierte la instancia en un servidor de autorización OAuth 2.0 completo para conectores que requieren OAuth (ChatGPT, Claude). Tokens de acceso JWT HS256 (24h, mismo archivo de clave HMAC que obols), cliente PKCE público chatgpt-mcp, descubrimiento de metadatos bajo /.well-known/, y una puerta de aprobación del propietario: el endpoint de autorización renderiza un formulario que exige la contraseña del propietario (MATAPAN_OAUTH_OWNER_PASSWORD al inicio del daemon — hasheada en memoria, nunca almacenada; el inicio rechaza el modo oauth sin ella). Sin inscripción abierta: solo se aceptan el cliente configurado y las URI de redirección en lista blanca. Los tokens se asignan a un principal agent-<client_id> específico del conector (AgentScopes: sin workspace.grant, sin proposal.apply) — el conector no puede conceder salida o secretos y no puede aplicar propuestas; la aplicación sigue siendo humana. La página de aprobación renderiza los alcances efectivos exactos. Los obols siguen funcionando junto con los JWT. matapan config oauth-setup imprime las instrucciones exactas del conector.
  • Retención de auditoría: ledger.retention_days (90) y ledger.max_entries (1e6); el barrendero de inicio/diario compacta con una entrada ancla para que Verify aún valide la cola retenida.

Configuración de tiempo de ejecución

La sección runtime de config.json establece los valores predeterminados por ejecución (timeout_sec, memory_mb, pids_limit, nano_cpus, max_output_bytes). Los valores por llamada pueden reducirlos pero nunca elevarlos más allá de los límites duros, que son constantes en internal/runtime (no configurables): tiempo de espera ≤ 10 min, memoria ≤ 4 GiB, salida capturada/transmitida ≤ 4 MiB. Las imágenes están fijadas por digest (docker_image) y verificadas después de cada pull; la procedencia vive en la tabla runtime_images (matapan runtime images).

Precedencia de configuración y anulaciones de entorno

Precedencia, siempre: env > archivo > predeterminados. Cada variable MATAPAN_* se aplica después de que se carga el archivo de configuración, antes de la validación; los valores inválidos fallan cerrados con un error que nombra la variable.

VariableMeaningDefault
MATAPAN_LISTEN_ADDRDirección de enlace HTTP127.0.0.1:18777
MATAPAN_DB_PATHBase de datos de control SQLite~/.matapan/matapan.db
MATAPAN_WORKSPACE_ROOTDirectorio raíz del espacio de trabajo~/.matapan/workspaces
MATAPAN_DOCKER_IMAGEImagen de ejecución fijada por digestalpine:3.23 pinned
MATAPAN_OBOL_KEY_PATHClave HMAC de obol (0600)~/.matapan/obol.key
MATAPAN_SECRET_KEY_PATHClave AES de secretos (0600)~/.matapan/secret.key
MATAPAN_ALLOW_LANtrue/false enlace no loopbackfalse
MATAPAN_TOOL_PROFILEminimal/fullminimal
MATAPAN_AUTH_MODElocal/charonlocal
MATAPAN_CHARON_URLEndpoint de validación de Charon—
MATAPAN_GC_IDLE_HOURSExpiración de espacio de trabajo inactivo (int)72
MATAPAN_LEDGER_RETENTION_DAYSRetención de auditoría (int)90
MATAPAN_LEDGER_MAX_ENTRIESLímite de auditoría (int)1000000
MATAPAN_RUNTIME_ISOLATIONdocker/gvisordocker
MATAPAN_OAUTH_CLIENT_IDclient_id público de OAuth (modo oauth)chatgpt-mcp

Contenedor

scripts/docker-build.sh matapan:local   # builds + version-stamps the image

docker run -d --name matapand \
  -p 127.0.0.1:18777:18777 \
  -v /etc/matapan/config.json:/etc/matapan/config.json:ro \
  -v ~/.matapan:/data \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v "$HOME/src:$HOME/src" \
  matapan:local

Se requiere paridad de rutas: la raíz del espacio de trabajo y cualquier repositorio fuente deben montarse en la misma ruta absoluta dentro y fuera del contenedor — matapand monta bind de los directorios del espacio de trabajo en los contenedores de ejecución y ejecuta operaciones de worktree de git contra rutas del host. Ver docs/operations.md para la guía completa de despliegue de contenedores (incluyendo el diseño de compose por modelo) y la nota de confianza de docker.sock. La imagen se ejecuta como root (documentado en el Dockerfile): el grupo del socket de Docker varía según el host; las cargas de trabajo de agentes aún se ejecutan bajo el perfil endurecido completo.

Resumen de seguridad

  • Sin shell en ningún lugar. Todos los subprocesos son arreglos argv os/exec; no hay ruta sh -c en el código base.
  • Defensa de rutas del espacio de trabajo. Cada llamada de herramienta de archivo re-canonicaliza con filepath.EvalSymlinks y rechaza escapes .. y escapes de symlink desde la raíz del espacio de trabajo, con una re-verificación TOCTOU al abrir.
  • Entorno de ejecución de contenedor endurecido. Usuario no root, CapDrop: ALL, sin nuevos privilegios, seccomp predeterminado, límites de memoria/CPU/PID, rootfs de solo lectura, NetworkMode: none por defecto (se requiere concesión de salida explícita), imágenes fijadas por digest con verificación de digest posterior al pull, lista blanca de entorno explícita (sin entorno de host ambiental), y un rechazo firme del modo privilegiado, PID/IPC de host, y cualquier montaje /var/run/docker.sock. Los contenedores se nombran matapan-<workspace>-<seq> y se etiquetan para que la destrucción y la reconciliación puedan encontrarlos; la limpieza se verifica, no se confía. La evidencia de comando incluye código de salida, bandera de muerte por OOM, digest de imagen verificado, razón de terminación y salida acotada (marcada por truncamiento).
  • Propuestas inmutables + aplicación CAS. Una propuesta sella el diff, los commits base/head y un digest de contenido. La aplicación verifica que el head de la rama objetivo sea igual tanto a la base de la propuesta como a tu expected_base, fusiona primero en un worktree temporal y es idempotente en la reproducción. Una base obsoleta devuelve un error tipado que lleva el head actual.
  • Ledger de auditoría. Solo anexión, encadenado por hash, redactado antes de la persistencia — los valores secretos nunca se almacenan (ledger.Redact).
  • Autenticación Obol. Tokens de portador HMAC-SHA256 (obol_<id>_<secret_hex>), revocables, audiencia fijada a matapan.
  • Defensa de importación de instantáneas. Las fuentes no Git se copian, nunca se referencian: raíz de fuente canonicalizada, symlinks que escapan se omiten y registran, FIFOs/dispositivos rechazados, límites de bytes/archivos, aperturas de fuente defendidas por TOCTOU.
  • Seguridad del ciclo de vida. Bloqueo por espacio de trabajo (mutex en proceso + flock, seguro ante fallos), destrucción permitida desde cualquier estado con verificación posterior a la eliminación, reconciliación de inicio para espacios de trabajo atascados/huérfanos, y contenedores etiquetados por Matapan eliminados al destruir.

Lenguaje honesto de aislamiento: esto es aislamiento de contenedor endurecido, no "ejecución segura". Los perfiles gVisor/Kata/microVM son la ruta de mayor garantía (gVisor es experimental a partir del Sprint 8). Detalle honesto completo: docs/docker-limitations.md.

Diseño

cmd/matapand        daemon (MCP over stdio or authenticated HTTP)
cmd/matapan         CLI (workspace/proposal/policy/secret/gc/runtime/doctor/config)
internal/config     daemon config + obol signing key load/generate
internal/obol       HMAC-SHA256 token service (audience "matapan")
internal/auth       identity adapter (local obols / Charon validate endpoint)
internal/policy     principals, scopes, workspace grants, named policy profiles
internal/ledger     hash-chained append-only audit + retention sweeps
internal/idempotency key-based dedup
internal/store      SQLite schema, migrations, typed store
internal/workspace  lifecycle, worktrees, snapshots, locking, leases + GC,
                    canonical path defense
internal/reconcile  startup crash recovery + orphan reconciliation
internal/runtime    hardened Docker exec, verified images, egress proxy wiring
internal/egressproxy allowlisting CONNECT/HTTP egress proxy
internal/secrets    AES-256-GCM secret registry + grant lifecycle
internal/proposal   seal, CAS apply strategies, conflict handling, revise
internal/testparse  JUnit/TAP evidence parsing (matapan-observed)
internal/mcpserver  workspace-scoped MCP tools (mcp-go v0.56.0)
internal/httpserver daemon HTTP (/api/health, /mcp)
scripts/            install.sh + release.sh packaging
docs/               threat model, ADRs, quickstarts, operations, acceptance

Licencia

MIT — Copyright (c) 2026 OpenLethe. Ver LICENSE.