Skip to main content
Glama

TÁNDEM

Refinamiento cruzado entre dos LLM — Claude Code CLI × Codex CLI — que trabajan en paralelo sobre copias aisladas del mismo material, se critican mutuamente con evidencia re-ejecutada, absorben cada uno lo mejor del otro y solo convergen cuando se cumple un predicado de excelencia computable (gates verdes + doble APPROVE + puntuación mínima).

Este repositorio implementa la arquitectura descrita en tandemarquitectura.md (proyecto LLM COLLAB). Las referencias §N de los comentarios del código apuntan a las secciones de ese documento.


1. Estado actual: esqueleto + base técnica

Módulo

Fichero(s)

Estado

Protocolo de mensajes (§5)

src/protocol/schemas.ts

✅ Completo: schemas zod de Finding, Critique, WorkResult, TaskSpec, EvidenceReport, TandemConfig, WorkPackage, ReviseInput, Rebuttal + parseAgentJson (extracción y auto-reparación de JSON)

Plantillas de prompt (§10)

src/protocol/prompts/*.md + prompts.ts

✅ Las 6 plantillas (spec-sync, produce, critique, revise, merge, audit) + motor de renderizado con bloques condicionales

Máquina de estados (§3)

src/orchestrator/state-machine.ts

✅ Fases, transiciones legales validadas, estado del run, helpers de ronda

Controlador de convergencia (§6)

src/orchestrator/convergence.ts

checkConvergence + isStagnant con lógica real y tests (incluye anti-adulación)

Ejecución de ronda (§3–§4)

src/orchestrator/round.ts

✅ Generalizada PRODUCE|REVISE ∥ → snapshots git → gates → crítica cruzada ∥ → adjudicación; cancelación del hermano si un agente cae; test de integración sobre repo git real

Bucle completo (Fase 2)

src/orchestrator/loop.ts

✅ SPEC_SYNC negociado (proponer→fusionar→votar, 2 intentos→ESCALATE) · bucle multironda con CHECK · REBUTTAL con contra-evidencia re-ejecutada · MERGE con integrador rotatorio · FINAL_AUDIT por el que NO integró · una corrección acotada · DELIVER copy-out · kill-switch cooperativo

Adaptadores (§7)

src/adapters/

produce()/critique()/revise() + ask() genérico validado en ambos. Claude: stdin + auto-reparación con --resume + sesión encadenada entre rondas. Codex: exec - + --output-schema. Modelos configurables por agente

Workspace Manager (§9)

src/workspace/

✅ copy-in + repo interno + worktrees (A/B/merge) + install por worktree + deliver copy-out (sin .git ni node_modules)

Evidence Runner (§8)

src/evidence/

runGates + adjudicación de findings + adjudicación de contra-evidencia (REBUTTAL, semántica inversa); rúbrica/links (modo docs) — Fase 3

Informes

src/orchestrator/report.ts

✅ Por ronda (comparativo) + final multironda: tabla de rondas, fusión y auditoría, backlog no bloqueante de minors, mapa de discrepancias si ESCALATE

Persistencia (§9)

src/store/

✅ SQLite (runs/rounds/messages + history para resume) + transcript JSONL append-only, alimentados en vivo

CLI (§12)

src/index.ts

✅ COMPLETO: run (bucle entero) · status · report · stop (sentinela) · resume (frontera de ronda o directo a MERGE) · doctor

Cabina MCP — Variante B (§14)

src/mcp/server.ts + mcp/server.ts

✅ Servidor MCP stdio para Claude Desktop: 7 tools (tandem_start/status/report/stop/resume/list/doctor), runs en segundo plano, testeado con cliente MCP real. Setup: mcp/README.md

Modo docs funcional

src/evidence/validators/docs-structure.ts

✅ Gate mecánico de memorias vía tandem.docs.json: cobertura LITERAL del baremo, secciones en espejo, anticontaminación (términos vetados), límites de extensión, cero «rojos», ficheros exigidos; + links locales

Eje de entornos

src/workspace/agent-env.ts

agentEnv: personal (cada cuenta con su arsenal — duelo de EQUIPOS; cada modelo interpreta sus skills a su manera, declarándolo en NOTES) | clean (solo auth — duelo de MODELOS); manifiesto arsenal.json por run; sharedTools MCP idénticas a ambos CLIs (metro común)

Verticales

src/verticals.ts + verticals/

✅ Arquitecturas especializadas como DATOS (config + normas + plantillas), kernel ciego al dominio. Primero: licitaciones (método NextHorizont: espejo del baremo, anclaje literal, anticontaminación) — --vertical licitaciones

Ejecución compartida

src/execute.ts

executeLoop + buildResumeState comunes a CLI y MCP (logger inyectable; store SIEMPRE por import dinámico)

Dashboard / MCP (§12, §14)

dashboard/, mcp/

🔲 Placeholders con diseño — Fase 3

Leyenda: ✅ implementado y testeado · 🟡 parcial (lo indicado pendiente) · 🔲 diseñado, sin código.


Related MCP server: compare-mcp

2. Requisitos

  1. Node ≥ 20 (probado con Node 22).

  2. pnpm (corepack enable o https://pnpm.io/installation).

  3. git en el PATH (los worktrees son el mecanismo de aislamiento).

  4. Claude Code CLI con login de tu suscripción (claude en el PATH).

  5. Codex CLI con codex login de tu suscripción ChatGPT.

Los CLIs solo hacen falta para ejecutar runs reales; para desarrollar y testear el orquestador no se necesitan.


3. Puesta en marcha, paso a paso

# 1) Entra en la carpeta del proyecto
cd tandem

# 2) Instala dependencias (siempre pnpm, nunca npm)
pnpm install

# 3) Comprueba que el esqueleto compila con TypeScript estricto
pnpm typecheck

# 4) Ejecuta la batería de tests (convergencia, máquina de estados, protocolo)
pnpm test

# 5) Diagnóstico del entorno: qué CLIs tienes y cuáles faltan
pnpm dev doctor

# 6) DUELO COMPLETO (Fase 2): bucle entero hasta la entrega auditada
pnpm dev run --dir ..\mi-carpeta --task "Tarea concreta y verificable"
#
#    Fases (cada ronda tarda MINUTOS — §16.1):
#      SPEC_SYNC (pactan la spec) → PRODUCE ∥ → gates → crítica cruzada
#      → adjudicación → REBUTTAL (contra-evidencia) → CHECK
#      → [REVISE con polinización cruzada → …]* hasta MERGE o ESCALATE
#      → fusión dirigida (integrador rotatorio) → FINAL_AUDIT (el otro)
#      → entrega en runs/<id>/final (o --out <carpeta>)
#
#    Flags útiles:
#      --blind            crítica sin autoría (Solución 1/2)
#      --no-spec-sync     usar la tarea literal como spec
#      --no-rebuttal      sin fase de contra-evidencia
#      --integrator claude|codex|auto
#      --model-claude X · --model-codex Y
#      --max-rounds 4 · --threshold 90 · --out D:\resultado

# 7) Control del run en vuelo (desde otra terminal)
pnpm dev status <run-id>     # rondas, gates, scores, decisiones
pnpm dev stop <run-id>       # kill-switch: para en la próxima frontera de fase
pnpm dev resume <run-id>     # reanuda desde la última ronda persistida
pnpm dev report <run-id>     # imprime el informe final

Notas: ambos CLIs deben tener login hecho (claude y codex login); tu carpeta original nunca se toca (copy-in → todo pasa en runs/<id>/, y la entrega es copy-out); resume re-produce la ronda que estaba en vuelo sobre los worktrees existentes.


4. Estructura del repositorio (§11)

tandem/
├── package.json                  # pnpm · Node ≥ 20 · ESM · TypeScript estricto (sin `any`)
├── tsconfig.json
├── src/
│   ├── index.ts                  # CLI (commander): run · status · report · resume · doctor · stop
│   ├── orchestrator/
│   │   ├── state-machine.ts      # fases y transiciones (§3)
│   │   ├── round.ts              # ejecución de una ronda (§3–§4)  [Fase 1]
│   │   └── convergence.ts        # checkConvergence + isStagnant (§6)
│   ├── adapters/
│   │   ├── agent-adapter.ts      # interfaz común + AgentContext (§7)
│   │   ├── claude-code.ts        # claude -p / --resume (headless)
│   │   └── codex.ts              # codex exec / resume / --output-schema (headless)
│   ├── protocol/
│   │   ├── schemas.ts            # zod: TODOS los mensajes agente↔orquestador (§5)
│   │   ├── prompts.ts            # carga y renderizado de plantillas
│   │   └── prompts/              # spec-sync · produce · critique · revise · merge · audit (§10)
│   ├── workspace/
│   │   ├── git.ts                # helpers git (repo interno del run)
│   │   ├── worktrees.ts          # ws-A / ws-B / ws-merge (§9)
│   │   ├── diff.ts               # snapshots etiquetados r<N>-A/B y diffs
│   │   └── merge.ts              # entrega fast-forward / copy-out  [Fase 2]
│   ├── evidence/
│   │   ├── runner.ts             # runGates + replayEvidence (el árbitro no-LLM, §8)
│   │   └── validators/           # typecheck · lint · tests · build · rubric · links
│   └── store/
│       ├── db.ts                 # SQLite: runs · rounds · messages (coste/latencia)
│       └── transcript.ts         # JSONL append-only auditable
├── test/                         # vitest: convergencia · máquina de estados · protocolo
├── dashboard/                    # Fase 3 (Next.js, Server Components sobre la SQLite)
└── mcp/                          # Fase 3 (variante B: cabina de mando en Claude Desktop)

5. Decisiones técnicas ya cerradas en el esqueleto

  1. ESM + NodeNext: imports con extensión .js obligatoria. TypeScript en modo máxima estrictez (strict, noUncheckedIndexedAccess, exactOptionalPropertyTypes); el tipo any está prohibido.

  2. El APPROVE nunca contradice la evidencia: implementado en convergence.ts (no confiado al modelo) y testeado en test/convergence.test.ts (caso "ANTI-ADULACIÓN").

  3. Sin checks aplicables no hay pase gratis: runGates devuelve pass=false si ningún validador aplica — obliga a configurar gates o rúbrica antes de que nada pueda aprobarse.

  4. Un finding sin evidencia no existe: FindingSchema exige evidence no vacía; la re-ejecución (replayEvidence) la adjudica en Fase 1.

  5. Codex valida en origen, Claude en destino: Codex usa --output-schema (JSON conforme garantizado); para Claude, parseAgentJson + bucle de auto-reparación sobre la misma sesión (máx. 2 intentos).

  6. Identidad git local por run: el repo interno usa tandem-orchestrator <tandem@localhost> — no toca tu configuración global.

  7. Línea de comandos fija + datos por stdin (src/util/exec.ts): los CLIs se invocan con shell: true (imprescindible para los shims .cmd de Windows) pero el prompt NUNCA se interpola en la línea de comandos — viaja por stdin (claude -p y codex exec -). Cero problemas de escapado en cmd.exe y sh.

  8. Heurística de adjudicación documentada (src/evidence/runner.ts): buscadores (grep/rg) reproducen con exit 0; comandos normales con exit ≠ 0 o si la salida contiene la expectativa declarada tras ; citas si el fichero:línea existe. Los disputed no cuentan (§5) pero quedan en el informe y el transcript.

  9. La identidad de las críticas la normaliza el orquestador: author/target/round se sobreescriben tras el parseo — un agente no puede atribuirse la autoría que quiera (testeado).

  10. REBUTTAL con semántica inversa: la contra-evidencia del autor gana si su comando TIENE ÉXITO (exit 0 o expectativa presente) — al revés que un finding, donde el fallo demuestra el defecto. Contra-evidencia no ejecutable = finding mantenido (se exige comando, no prosa).

  11. SPEC_SYNC en tres pasos deterministas: proponer ∥ → fusiona uno → vota el otro; si rechaza, fusiona el que rechazó (con sus objeciones sobre la mesa) y vota el primero; segundo rechazo → ESCALATE spec_conflict. Barato de escalar en ronda 0, caro en ronda 4 (§3).

  12. Kill-switch cooperativo: tandem stop crea el sentinela STOP; el bucle lo consulta entre fases (los CLIs en vuelo no se matan a mitad). resume retoma en frontera de ronda re-produciendo la ronda en vuelo sobre los worktrees existentes.

  13. Cancelación del hermano: si un agente cae en una fase paralela, el otro se aborta vía AbortSignal → no quedan procesos huérfanos consumiendo cuota.

  14. Normas del duelo (Karpathy Guidelines adaptadas): los cuatro principios de multica-ai/andrej-karpathy-skills (MIT) — pensar antes de programar, simplicidad primero, cambios quirúrgicos, ejecución guiada por objetivos — se inyectan automáticamente en los prompts en DOS caras: norms-build.md para quien produce/revisa/fusiona y norms-review.md para quien critica/audita (los incumplimientos objetivos son material legítimo de finding, sin relajar la evidencia obligatoria ni habilitar bloqueos por estilo). Adaptación clave: el "pregunta si dudas" headless se canaliza a supuestos declarados en NOTES.md y ambigüedades resueltas en SPEC_SYNC. Se desactivan pasando NORMS: null a buildPrompt (o editando los .md).


6. Roadmap — qué implementar y en qué orden

Fase 1 — MVP (una ronda demostrable) — ✅ COMPLETADA (y validada con un duelo real en producción).

Fase 2 — Bucle completo — ✅ COMPLETADA (validada en producción: run cfa59ae1, fusión de codex auditada por claude y entregada).

Variante B — Cabina en Claude Desktop — ✅ COMPLETADA: servidor MCP local con runs en segundo plano (ver mcp/README.md).

Fase 3 — Confort (pendiente): dashboard Next.js, modo docs (rúbricas + links), contenedores, deliver fast-forward en modo-rama, sesión persistente de Codex (exec resume + eventos --json), tabla de rondas del informe reconstruida desde la BD en runs reanudados.

Fase 3 — Confort: dashboard Next.js, servidor MCP (variante B), modo docs (rúbricas + links), --blind operativo, presupuestos finos, contenedores.


7. Solución de problemas (Windows)

better-sqlite3 falla al instalar con «"node-gyp" no se reconoce…». El proyecto fija better-sqlite3@^12 a propósito: la v12 instala con prebuild-install || node-gyp rebuild, es decir, descarga un binario ya compilado para tu plataforma (hay binarios win32-x64 para Node 22 — ABI 127 — y Node 24 — ABI 137) y solo compila como último recurso. La v13 eliminó los binarios precompilados y SIEMPRE compila desde código, lo que en Windows exige Python + Visual Studio Build Tools. Si con la v12 sigue intentando compilar, tu versión de Node no tiene binario publicado: comprueba node -v y usa Node 22 o 24 LTS.

doctor decía que un CLI no estaba, pero sí está. En Windows, pnpm/claude/codex son shims .cmd, y Node (tras el parche de seguridad CVE-2024-27980) se niega a spawnearlos sin shell (error EINVAL). El doctor ya los invoca con shell: true. Verifica en una terminal nueva que claude --version y codex --version responden.

codex aborta con «Not inside a trusted directory». Es su puerta de confianza: en modo interactivo pregunta si confías en la carpeta; en headless no puede y aborta. TANDEM ya invoca codex exec con --skip-git-repo-check (seguro: el cwd es siempre el worktree git del run). Si lo ves, tu copia del adaptador es antigua.

codex escupe errores «failed to load skill … missing YAML frontmatter». Son NO fatales: codex rechaza skills personales de ~/.agents/skills/ cuyo SKILL.md no empieza por ---, y continúa. Puedes ignorarlos o poner esas skills en cuarentena para limpiar el ruido (muévelas a otra carpeta y reviértelo cuando quieras).

Runs reales en Windows. Los CLIs se lanzan con línea de comandos fija + prompt por stdin (ver decisión 7), que funciona en Windows nativo. Si tu instalación de codex no soportara --sandbox workspace-write en Windows, la alternativa es ejecutar los runs bajo WSL2.

8. Seguridad (§13) — ya reflejada en el esqueleto

  • Claude: --permission-mode acceptEdits + lista blanca CLAUDE_ALLOWED_TOOLS (nunca bypassPermissions fuera de contenedor).

  • Codex: --sandbox workspace-write (escritura limitada al worktree).

  • runs/ está en .gitignore (contiene worktrees y transcripts); .env fuera del árbol que ven los agentes.

  • Timeouts por fase (phaseTimeoutMs) y presupuesto por run (budgetMs) en la config.

F
license - not found
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Cross-agent artifact workspace with provenance across Claude Code, Codex, Cursor, LangGraph.

  • The team layer for AI coding agents: shared contracts, collision alerts, E2EE sessions.

  • Agent-native collaboration network: orchestrate a team of long-running agents from any MCP client.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/semaes111/TANDEM_MCP_TOKEN'

If you have feedback or need assistance with the MCP directory API, please join our Discord server