turbo rig / deep dive — the logic of everythingla lógica de todo

A file-by-file walkthrough of Turbo Rig — the agent-control system built on one thesis: model quality has converged; the harness and the loop are the differentiator. Three agents with fixed jobs, one shared spine of contracts, one verification loop. This page explains how every script and file actually works — the gate, the worktrees, the dashboards, the QA machinery, the automations — and the design logic underneath each one.Un recorrido archivo por archivo de Turbo Rig — el sistema de control de agentes construido sobre una sola tesis: la calidad de los modelos ha convergido; el harness y el bucle son el diferenciador. Tres agentes con trabajos fijos, una espina compartida de contratos, un bucle de verificación. Esta página explica cómo funciona de verdad cada script y archivo — la compuerta, los worktrees, los dashboards, la maquinaria QA, las automatizaciones — y la lógica de diseño debajo de cada uno.
repo · github.com/marcuspat/turbo-rig (private)repo · github.com/marcuspat/turbo-rig (privado) constitution · AGENTS.md v1 (2026-09-09)constitución · AGENTS.md v1 (2026-09-09) successor of Turbo Flowsucesor de Turbo Flow
bash + python3 onlysolo bash + python3no daemonssin daemonsfail-closedfallo-cerradocross-model reviewrevisión entre modelosv2 · 11 flowchartsv2 · 11 diagramas agents never mergelos agentes jamás fusionanstate on diskestado en disco

00What Turbo Rig is00Qué es Turbo Rig

Not a framework, not a runtime, not a product. A single git repo of contracts and scripts that wraps around existing agent harnesses.No es un framework, no es un runtime, no es un producto. Un único repo git de contratos y scripts que envuelve a los harnesses de agentes existentes.

The one-sentence definition, from the rig's own explainer: a harness drives an agent; a rig drives your harnesses. You have three AI coding agents that could each do anything — which is exactly the problem. Without structure you get three harnesses, an inert swarm layer, thousands of lines of shell config, and no reliable way to know if an agent's work is actually correct. The rig is the structure.La definición en una frase, del propio explicador del rig: un harness conduce un agente; un rig conduce tus harnesses. Tienes tres agentes de código con IA que podrían cada uno hacer cualquier cosa — que es exactamente el problema. Sin estructura terminas con tres harnesses, una capa de enjambre inerte, miles de líneas de configuración shell, y ninguna forma confiable de saber si el trabajo de un agente es realmente correcto. El rig es la estructura.

Concretely it is a repo (public convention ~/turbo-rig; the founder's clone is ~/rig) containing: a constitution every agent reads, one cross-model verification gate, worktree tooling, observability dashboards, QA report machinery, a schedule of self-checking automations, and a git-versioned memory tier. It has no runtime of its own and nothing to keep alive — the "roads and traffic lights" are git, GitHub, and files; orchestration emerges from shared data rather than from a coordinator.En concreto es un repo (convención pública ~/turbo-rig; el clon del fundador es ~/rig) que contiene: una constitución que todo agente lee, una compuerta de verificación entre modelos, herramienta de worktrees, dashboards de observabilidad, maquinaria de reportes QA, un calendario de automatizaciones auto-verificantes y un nivel de memoria versionado en git. No tiene runtime propio ni nada que mantener vivo — las "carreteras y semáforos" son git, GitHub y archivos; la orquestación emerge de los datos compartidos, no de un coordinador.

The load-bearing research (Sept 2026)La investigación load-bearing (sept 2026)

Everything the rig replaced was subtracted with reasons: the claude-flow/ruflo swarm layer (native harness features replaced it; its 689 shell aliases were collapsed into one on-demand file), Aider (unmaintained), Grok Build (walled beta), NVIDIA Avo (research system, no repo — but two of its ideas were stolen: persistent memory and a redirecting supervisor). The rig's own docs/WHY-NOT-THOSE-TOOLS.md keeps the full audit trail.Todo lo que el rig reemplazó fue sustraído con razones: la capa de enjambre claude-flow/ruflo (las funciones nativas del harness la reemplazaron; sus 689 aliases de shell se colapsaron en un archivo bajo demanda), Aider (sin mantenimiento), Grok Build (beta cerrada), NVIDIA Avo (sistema de investigación, sin repo — pero dos de sus ideas fueron robadas: memoria persistente y un supervisor que redirige). El propio docs/WHY-NOT-THOSE-TOOLS.md del rig conserva la pista de auditoría completa.

01Architecture — Triangle · Spine · Loop · Planes · Background01Arquitectura — Triángulo · Espina · Bucle · Planos · Fondo

Five named tiers. Every file in the repo belongs to exactly one of them.Cinco niveles con nombre. Cada archivo del repo pertenece a exactamente uno de ellos.

┌───────────────────────── MAC (control plane) ──────────────────────────┐
│  ZCode (cockpit)      Claude Code (builder+reviewer)    Codex (dormant)│
│        └───────────────┬──────────┴─────────────┘                       │
│              AGENTS.md constitution (~/turbo-rig — this repo)           │
│   skills (~/.agents/skills) · memory/ · specs/ · runbooks/ · qa/        │
│   gate: scripts/review.sh          worktrees: scripts/wt.sh             │
└───────────────────────────────┬─────────────────────────────────────────┘
                                │ git pull / gh
┌────────────────────── REMOTE (execution plane) ────────────────────────┐
│  VPS via DevPod SSH · gh Codespaces                                    │
│  builds, containers, yolo-permission agents — never on the Mac         │
└─────────────────────────────────────────────────────────────────────────┘
TierNivelWhat it isQué esFilesArchivos
TriangleTriánguloThree agents with fixed roles; the harness filling each role is a swappable roster choice.Tres agentes con roles fijos; el harness que llena cada rol es una elección intercambiable del roster.AGENTS.md (roster table)AGENTS.md (tabla del roster)
SpineEspinaThe shared rulebook + memory + skills every agent reads. One source of truth per concern; everything else imports it.El libro de reglas compartido + memoria + skills que todo agente lee. Una fuente de verdad por asunto; todo lo demás lo importa.AGENTS.md, memory/, ~/.agents/skills
LoopBuclespec → build → cross-model gate → human diff review → merge. Agents never merge.spec → construir → compuerta entre modelos → revisión humana del diff → fusión. Los agentes jamás fusionan.scripts/review.sh, scripts/wt.sh, specs/
PlanesPlanosMac = thin control plane (no Docker, no daemons). VPS/Codespaces = execution plane for anything heavy.Mac = plano de control flaco (sin Docker, sin daemons). VPS/Codespaces = plano de ejecución para lo pesado.scripts/remote.sh, runbooks/remote-execution.md
BackgroundFondoNine scheduled automations: digest, security scan, memory consolidation, retro, canaries…Nueve automatizaciones programadas: digest, escaneo de seguridad, consolidación de memoria, retro, canarios…automations/README.md, cards.sh
THE LOOP — every change, no exceptionsSPEC — delta specspecs/ (multi-dayonly)BUILD — one freshsession in wt.shworktreeCHECKS — $0pre-LLM--check lanesGATE — cross-modelreview.sh reviewVERDICT — failclosed parsePR + HUMANMERGE (Law 3)MERGE-QA —record + livechecksMEMORY —consolidatenightlyREVISE — fix, re-gatenext task

The Triangle — roles are fixed, harnesses are swappableEl Triángulo — los roles son fijos, los harnesses intercambiables

RoleRolJobTrabajoRosterWhyPor qué
Workhorse / builderCaballo de batalla / constructorVolume building, read-only scout fan-outs, scheduled/night work, cockpitConstrucción en volumen, abanicos de exploración en solo-lectura, trabajo nocturno/programado, cabinaZCode (GLM-5.3)Cheap tier, 1M-token context, idle-time tasks free. Building burns 10–50× the tokens of reviewing, so the cheap tier builds.Nivel barato, contexto de 1M tokens, tareas en tiempo ocioso gratis. Construir quema 10–50× los tokens de revisar, así que el nivel barato construye.
Frontier + reviewerFrontera + revisorHard multi-file work; the adversarial reviewer in the gateTrabajo difícil multi-archivo; el revisor adversarial de la compuertaClaude Code (Max)Strongest analyst on subscription — and cross-family review is the whole point.El analista más fuerte por suscripción — y la revisión entre familias es todo el punto.
ReserveReservaThird opinion; auto-used by the gate when auth existsTercera opinión; auto-usada por la compuerta cuando existe authCodexCosts nothing wired dormant; keeps the two-family rule satisfiable under quota pressure.No cuesta nada cableado dormido; mantiene la regla de dos familias satisfacible bajo presión de cuota.

Two inviolable roster rules: at least two model families, and the reviewer is never the builder's family (collapsing to one family is self-review — it deletes the cross-review effect the gate exists for). And there's a documented GLM-free variant for users who avoid Chinese vendors: Codex builds, Claude reviews. Swapping the roster is a ~15-minute recipe (runbooks/swap-roster.md) — machinery never changes, only the table does.Dos reglas de roster inviolables: al menos dos familias de modelos, y el revisor nunca es de la familia del constructor (colapsar a una sola familia es auto-revisión — borra el efecto de revisión cruzada por el que existe la compuerta). Y hay una variante documentada sin GLM para quienes evitan proveedores chinos: Codex construye, Claude revisa. Cambiar el roster es una receta de ~15 minutos (runbooks/swap-roster.md) — la maquinaria nunca cambia, solo cambia la tabla.

02The constitution — AGENTS.md02La constitución — AGENTS.md

The single source of truth for how agents behave. Tool-specific files import it; nothing duplicates it (drift is the enemy).La única fuente de verdad sobre cómo se comportan los agentes. Los archivos específicos de cada herramienta lo importan; nada lo duplica (la deriva es el enemigo).

At the top sits an ## Invariants section — machine-read by the gate itself (see §3): every review of the rig injects those invariants into the reviewer prompt, scrubbed and fenced as data. Violations are automatic REVISE. This is a repo writing laws for its own reviewer.Al inicio vive una sección ## Invariants — leída por máquina por la propia compuerta (ver §3): cada revisión del rig inyecta esos invariantes en el prompt del revisor, lavados y cercados como datos. Las violaciones son REVISE automático. Es un repo escribiendo leyes para su propio revisor.

The ten lawsLas diez leyes

#LawLeyEnforced byAplicada por
1Builder ≠ reviewer. Never review your own diff. Missing verdict = REVISE.Constructor ≠ revisor. Jamás revises tu propio diff. Veredicto faltante = REVISE.review.sh (roster + fail-closed parse)review.sh (roster + parse fallo-cerrado)
2Verdict protocol. Reviews end with exactly one line: VERDICT: APPROVED or VERDICT: REVISE — <reason>.Protocolo de veredicto. Las revisiones terminan con exactamente una línea: VERDICT: APPROVED o VERDICT: REVISE — <reason>.review.sh awk parseparse awk de review.sh
3Agents never force-push, merge, push to main, or approve their own PRs. Humans merge.Los agentes jamás hacen force-push, fusionan, empujan a main ni aprueban sus propios PRs. Los humanos fusionan.constitution + operator practiceconstitución + práctica del operador
4Isolation or permission, never neither. Parallel writers in separate worktrees; skip-permissions only in remote sandboxes.Aislamiento o permiso, nunca ninguno de los dos. Escritores en paralelo en worktrees separados; skip-permissions solo en sandboxes remotos.wt.sh, remote.sh
5Right-size ceremony. Small task → plan mode, no spec. Multi-day → delta spec first.Ceremonia a la medida. Tarea pequeña → modo plan, sin spec. Varios días → delta spec primero.specs/, runbooks
6Short fresh contexts beat long smart ones. Explore/plan/execute as separate steps.Los contextos frescos y cortos vencen a los largos e inteligentes. Explorar/planear/ejecutar como pasos separados.runbooks/operating-rhythm.md
7State lives on disk. Todos, fix-plans, specs, memory — in the repo, never only in a conversation. Memory recall is two-pass. Before ending a session, capture durable facts to memory files.El estado vive en disco. Todos, fix-plans, specs, memoria — en el repo, nunca solo en una conversación. El recall de memoria es de dos pasadas. Antes de cerrar una sesión, captura hechos durables a archivos de memoria.memory/ + nightly consolidationmemory/ + consolidación nocturna
8Subtraction over addition. Before adding any tool: what does it replace? One source of truth per concern.Sustraer antes que añadir. Antes de añadir una herramienta: ¿qué reemplaza? Una fuente de verdad por asunto.review culture, decisions.mdcultura de revisión, decisions.md
9Secrets never enter git, never plaintext. OS keychain; encryption (not hashing) for secrets that must be used.Los secretos jamás entran a git, jamás en claro. Keychain del SO; cifrado (no hash) para secretos que deben usarse.secret.sh, .gitignore (backup/)
10Report faithfully. Failing tests reported, skipped steps stated, no silent fallbacks.Reportar con fidelidad. Tests fallidos reportados, pasos saltados enunciados, sin fallbacks silenciosos.selftests, merge-qa verdictsselftests, veredictos de merge-qa

Queue ownership — the gate log as heartbeatPropiedad de cola — el log de la compuerta como latido

A doctrine born from a real incident: a cockpit misread a live gating cycle as an idle queue and offered a sweep that would have double-gated two in-flight PRs. The fix: read the gate log as a heartbeat, not a snapshot. A gate-log run for a PR in the last 30 minutes from a different worktree means another session owns it mid-loop — the gate refuses (exit 4). Your own worktree's fresh runs are your own loop. Override: GATE_FORCE=1.Una doctrina nacida de un incidente real: una cabina malinterpretó un ciclo de compuerta activo como una cola ociosa y ofreció un barrido que habría pasado dos PRs en vuelo por doble compuerta. La corrección: leer el log de la compuerta como un latido, no como una instantánea. Una corrida del gate-log para un PR en los últimos 30 minutos desde otro worktree significa que otra sesión lo posee a medio bucle — la compuerta se rehúsa (exit 4). Las corridas frescas de tu propio worktree son tu propio bucle. Override: GATE_FORCE=1.

QUEUE OWNERSHIP — the gate log as heartbeat (not asnapshot)MY_WT = basename ofworktreetoplevel — the same keythe gate log writesscan gate-log: rows forpr#Nwhere repo ≠ MY_WT —newestts within 30 min?fresh foreign run found→owned by another sessionGATE_FORCE=1 ?proceed — you are theowner(own fresh runs neverblock)yesno → exit 4 refusalyesno foreign run

03The gate — scripts/review.sh03La compuerta — scripts/review.sh

The heart of the rig: a 959-line bash file that makes a different model family review every diff before merge, and turns its answer into a machine-parseable, fail-closed verdict.El corazón del rig: un archivo bash de 959 líneas que hace que una familia de modelo distinta revise cada diff antes de la fusión, y convierte su respuesta en un veredicto parseable por máquina, de fallo-cerrado.

parse argsreviewer · base · pr · checksparsear argsreviewer · base · pr · checks→ canonicalize repo-C path → absolutecanonizar repo-C path → absolute→ gather diffstdin | gh pr diff | git diffreunir diffstdin | gh pr diff | git diff→ ownership checkgate-log heartbeatcheck de propiedadgate-log heartbeat→ deterministic checks--check · $0 · secondschecks deterministas--check · $0 · seconds→ inject invariantsbase ref, scrubbedinyectar invariantesbase ref, scrubbed→ dispatch reviewerclaude | codex | custom | file:despachar revisorclaude | codex | custom | file:→ parse verdictfail closedparsear veredictofail closed→ log usagegate-log.jsonlregistrar usogate-log.jsonl→ post PR commentGitHub = state machinecomentario de PRGitHub = state machine
GATE I — argument guard, diff gathering, queue ownershipreview.sh [flags]--pr N · --stdin ·branchreviewer enum valid?exit 2 — usage errormode dispatch--sweep: walk openPRs,skip already-gated,classify each child0=all OK · 1=REVISE · 4=skipPR mode: gh apiexistence checkforeign worktree gatedthis PR < 30 min ago?exit 4 — owned byanother sessionoverride: GATE_FORCE=1gh pr diff Nstdin: read diffempty? exit 2(fail-closed)branch: verify base+headrefs (unknown → exit 2)git diff--merge-baseempty diff → exit 0nothing to gateDIFF in hand → GateIInoyesno / forcedemptyyes, no forceempty

Exit-code contractContrato de códigos de salida

exitmeaningsignificado
0APPROVED
1REVISE — or an unparseable verdict: no verdict line parses ⟹ REVISE. Uncertainty is never a pass.REVISE — o un veredicto inparseable: ninguna línea de veredicto parsea ⟹ REVISE. La incertidumbre jamás es un pase.
2error — bad flags, unknown base/head refs (a typo'd ref must never pass as "empty diff"), empty stdin, reviewer unavailableerror — flags malos, refs base/head desconocidos (un ref con typo jamás debe pasar como "diff vacío"), stdin vacío, revisor no disponible
3--selftest failurefallo de --selftest
4ownership refusal — another session owns this PR (the queue heartbeat)rechazo de propiedad — otra sesión posee este PR (el latido de la cola)

The review promptEl prompt de revisión

Every reviewer gets the same adversarial brief: review only the diff, no tools, no file reads; hunt in order — correctness bugs, security issues (injection, leaked secrets, unsafe handling of untrusted input), broken error handling, missing tests for changed behavior; cite file:line for every finding; ignore pure style; end with exactly one verdict line. The diff is appended under a --- DIFF --- separator. Reviews are deliberately read-only and context-free: the reviewer can't be socialized by the codebase, only by the delta.Cada revisor recibe la misma consigna adversarial: revisar solo el diff, sin herramientas, sin leer archivos; cazar en orden — bugs de corrección, problemas de seguridad (inyección, secretos filtrados, manejo inseguro de entrada no confiable), manejo de errores roto, tests faltantes para el comportamiento cambiado; citar file:line por cada hallazgo; ignorar puro estilo; terminar con exactamente una línea de veredicto. El diff se adjunta bajo un separador --- DIFF ---. Las revisiones son deliberadamente de solo-lectura y sin contexto: al revisor no puede socializarlo el código base, solo el delta.

Proofs before prophets — repo invariantsPruebas antes que profetas — invariantes de repo

If the repo under review has an ## Invariants section in its AGENTS.md, the gate injects it into the prompt as claims to check, never instructions. Three defenses make this injection-proof:Si el repo bajo revisión tiene una sección ## Invariants en su AGENTS.md, la compuerta la inyecta en el prompt como afirmaciones-a-verificar, nunca como instrucciones. Tres defensas la vuelven a prueba de inyección:

Deterministic checks — the $0 pre-LLM laneChecks deterministas — el carril de $0 pre-LLM

--check '<cmd>' (repeatable) runs operator commands — tsc --noEmit, a test suite, a linter — in the repo before any LLM lane fires. A failing check is the REVISE verdict: the script fabricates the review body (check name, exit code, last 20 lines of scrubbed output) and the reviewer never runs — quota saved, seconds not minutes. Checks break on first failure (a sentinel-proven non-execution of later checks), and PR/stdin modes stamp an honesty note that the check ran against the local working tree, not the PR head.--check '' (repetible) corre comandos del operador — tsc --noEmit, una suite de tests, un linter — en el repo antes de que cualquier carril LLM se dispare. Un check que falla es el veredicto REVISE: el script fabrica el cuerpo de la revisión (nombre del check, código de salida, últimas 20 líneas de salida lavada) y el revisor nunca corre — cuota ahorrada, segundos en vez de minutos. Los checks cortan en el primer fallo (no-ejecución de los checks posteriores probada por centinela), y los modos PR/stdin estampan una nota de honestidad de que el check corrió contra el árbol local, no contra el head del PR.

Reviewer lanesCarriles de revisor

claude (default)claude (por defecto)

Prompt+diff piped to headless claude -p. Tries JSON envelope variants first (they carry token usage + cost), degrades layer by layer — --bare --output-format json → plain JSON → bare text — so a CLI auth quirk degrades usage reporting, never the verdict. Detects the "Not logged in" envelope and prints the exact fix (claude login).Prompt+diff entubados al claude -p headless. Prueba primero variantes de sobre JSON (llevan uso de tokens + costo), degrada peldaño por peldaño — --bare --output-format json → JSON plano → texto plano — para que una rareza de auth del CLI degrade el reporte de uso, nunca el veredicto. Detecta el sobre "Not logged in" e imprime la corrección exacta (claude login).

codex (reserve)codex (reserva)

Runs codex exec --sandbox read-only --json (sandbox always — published AGENTS.md injection research). Anchors in a throwaway empty git repo in scratch space, never the reviewed repo — codex demands a git cwd, but granting a real one only adds unneeded read scope. Completeness proof: exit 0 and the terminal turn.completed event parsed — a timed-out stream that looks parseable is rejected. Fallback re-runs the review; empty output is failure, never a pass.Corre codex exec --sandbox read-only --json (sandbox siempre — investigación publicada sobre inyección en AGENTS.md). Ancla en un repo git vacío desechable en espacio de rasguño, jamás en el repo revisado — codex exige un cwd git, pero darle uno real solo añade alcance de lectura innecesario. Prueba de completitud: exit 0 y el evento terminal turn.completed parseado — un flujo con timeout que parece parseable se rechaza. El fallback re-corre la revisión; salida vacía es fallo, nunca un pase.

custompersonalizado

--reviewer-cmd '<anything>' — any headless harness that reads the prompt on stdin and prints a review ending in the verdict line becomes a rig reviewer. The machinery is deliberately harness-neutral.--reviewer-cmd '' — cualquier harness headless que lea el prompt de stdin e imprima una revisión que termina en la línea de veredicto se vuelve un revisor del rig. La maquinaria es deliberadamente neutral al harness.

file: (debug)file: (depuración)

--reviewer file:path cats a canned review — hermetic testing of the verdict machinery with zero auth, zero cost. A debug stand-in reviews no laws (invariants are skipped for it).--reviewer file:path escupe una revisión enlatada — pruebas herméticas de la maquinaria de veredicto con cero auth, cero costo. Un suplente de depuración no revisa leyes (los invariantes se omiten para él).

GATE II — deterministic checks, invariant injection,reviewer dispatchDIFF in hand--check lanesconfigured?run each check in repo(seconds · $0 ·break-on-first-fail)fail → fabricateREVISE(check · exit code ·scrubbed tail) —reviewer never runsWHO=check · $0 · 0 tokensgate-log row still writtenrepo has ## Invariantsand reviewer ≠ file: ?read AGENTS.md at BASE refstrip VERDICT: lines (anycase)fence as <<>>ENDstdin mode: no base to trust — skipped--reviewer ?forced lanes: claude(default) ·codex (reserve) · custom/ file:any headless harnessauto: probe claude 7-dayquota (Keychain →endpoint).util ≥ 75% & codex authed?→ codex lane(quota conserved)→ claude lane(probe fail =absent)fallback chains: claude envelope → bare text · codexcompleteness proof → full re-run · empty output = failure,never a passyesnoany failall pass → LLM lane followsyesno / assembledforcedauto (default)yesno / ERR / empty

The claude degradation ladderLa escalera de degradación de claude

One reviewer, four rungs, each checking the envelope before trusting it: --bare --output-format json (richest — carries usage + cost) → plain --output-format json → bare text prompt → plain text. An auth-broken envelope ("Not logged in" in result) is discarded at the parse step, not mistaken for an empty review. Every degrade costs only the usage row — the verdict path survives any CLI quirk.Un revisor, cuatro peldaños, cada uno verificando el sobre antes de confiar en él: --bare --output-format json (el más rico — lleva uso + costo) → --output-format json plano → prompt de texto plano → texto plano. Un sobre con auth rota ("Not logged in" en result) se descarta en el paso de parse, no se confunde con una revisión vacía. Cada degradación cuesta solo la fila de uso — la ruta del veredicto sobrevive cualquier rareza del CLI.

The codex completeness proofLa prueba de completitud de codex

codex streams JSON events; the review text is the last agent_message, and the proof the stream wasn't truncated mid-flight is the terminal turn.completed event — detected by whether the usage parser produced output, not by grepping a brittle literal. Exit 0 alone is insufficient: a killed stream can leave a parseable-but-partial message. Incomplete → full fallback re-run (double latency, the cost of a schema shift is a second call, never the verdict); still empty → failure (return 1) so auto can fall through to the other reviewer. The scratch-anchor trick: codex demands a git cwd, so the gate mints a throwaway empty repo in mktemp space — anchoring in the reviewed repo would only grant unneeded read scope to a reviewer forbidden from reading anything.codex transmite eventos JSON; el texto de la revisión es el último agent_message, y la prueba de que el flujo no fue truncado a medio vuelo es el evento terminal turn.completed — detectado por si el parser de uso produjo salida, no grepeando un literal frágil. Exit 0 solo es insuficiente: un flujo matado puede dejar un mensaje parseable-pero-parcial. Incompleto → re-ejecución completa de fallback (doble latencia; el costo de un cambio de esquema es una segunda llamada, nunca el veredicto); aún vacío → fallo (return 1) para que auto pueda caer al otro revisor. El truco del ancla de rasguño: codex exige un cwd git, así que la compuerta acuña un repo vacío desechable en espacio mktemp — anclar en el repo revisado solo le daría alcance de lectura innecesario a un revisor al que le está prohibido leer.

Quota-aware auto dispatchAuto-despacho consciente de cuota

--reviewer auto (the default) keeps the gate inside the subscription. It reads Claude's live 7-day plan utilization — OAuth token pulled from macOS Keychain, called against Anthropic's own usage endpoint, token traveling via curl's stdin config so it never appears in ps — and if utilization is ≥ GATE_QUOTA_THRESHOLD (default 75%) and codex is authed, it dispatches codex for that run and says why. Any probe failure (no keychain, no token, bad JSON) means "signal absent" → stay claude-first. The dispatch function is pure arithmetic over two arguments, which is exactly why it's unit-testable from selftest.--reviewer auto (el default) mantiene la compuerta dentro de la suscripción. Lee la utilización viva del plan de Claude a 7 días — token OAuth jalado del Keychain de macOS, consultando el propio endpoint de uso de Anthropic, el token viaja vía la config stdin de curl para que nunca aparezca en ps — y si la utilización es ≥ GATE_QUOTA_THRESHOLD (default 75%) y codex está autenticado, despacha codex para esa corrida y dice por qué. Cualquier fallo de sonda (sin keychain, sin token, JSON malo) significa "señal ausente" → mantener claude-primero. La función de despacho es aritmética pura sobre dos argumentos — exactamente por eso es unit-testeable desde el selftest.

Sweep modeModo barrido

--sweep walks every open PR (limit 50), skips any that already carries a gate verdict comment (force re-review with --pr N), gates the rest, and classifies each child run: ok (exit 0), fail (verdict or error), or skip (ownership refusal exit 4). The summary line is faithful by construction — four distinct shapes for "nothing open / nothing reviewed / mixed / clean" so a no-op can never read as a green sweep.--sweep recorre cada PR abierto (límite 50), se salta los que ya llevan un comentario de veredicto de la compuerta (forzar re-revisión con --pr N), compuerta al resto y clasifica cada corrida hija: ok (exit 0), fail (veredicto o error) o skip (rechazo de propiedad exit 4). La línea de resumen es fiel por construcción — cuatro formas distintas para "nada abierto / nada revisado / mixto / limpio", así un no-op nunca puede leerse como un barrido verde.

The audit trail — gate-log.jsonlEl rastro de auditoría — gate-log.jsonl

Every run appends one JSON row to ~/.local/state/turbo-rig/gate-log.jsonl: timestamp, repo (worktree basename — the ownership key), target (pr#N or base..head), reviewer, verdict, in/cached/out tokens, API-equivalent cost, duration, model. The log is append-only truth: it feeds ownership checks, both dashboards, the digest's merge queue, merge-QA reports, and the weekly retro. Check-decided runs log a zero-token row with reviewer: check — the trail is complete even when no LLM ran.Cada corrida agrega una fila JSON a ~/.local/state/turbo-rig/gate-log.jsonl: timestamp, repo (nombre base del worktree — la llave de propiedad), target (pr#N o base..head), revisor, veredicto, tokens in/cached/out, costo API-equivalente, duración, modelo. El log es verdad de solo-agregar: alimenta los checks de propiedad, ambos dashboards, la cola de fusión del digest, los reportes merge-QA y el retro semanal. Las corridas decididas-por-check loguean una fila de cero tokens con reviewer: check — el rastro queda completo incluso cuando ningún LLM corrió.

GATE III — verdict parse (fail closed), audit trail, PRcommentreviewer output$OUTawk: last line matchingVERDICT: APPROVED|REVISE ?RC 0 · GATE:APPROVEDRC 1 · GATE:REVISEfix and re-gateRC 1 anyway — NO VERDICTPARSED = REVISE (failclosed)usage_report → append oneJSON rowto gate-log.jsonl (tokens ·cost ·duration · model)PR mode?gh pr comment — lanes +usage +review + verdict · GitHubbecomesthe state machinebranch mode: stdoutonlyAPPROVEDREVISEnone / garbageevery run logs — even check-decided (0-token row)yesno

Anatomy of a gate-log rowAnatomía de una fila del gate-log

One JSON line per run — the atom every downstream tool joins on:Una línea JSON por corrida — el átomo sobre el que se une toda herramienta aguas abajo:

{"ts": "2026-09-21T22:06:15",            // naive LOCAL time — the tokens.py convention
 "repo": "prd25-og-locale",                // worktree basename — the ownership key + lane label
 "target": "pr#429" | "main..HEAD",        // PR mode vs branch mode
 "reviewer": "claude" | "codex" | "check", // WHO decided — "check" = deterministic lane
 "result": "GATE: APPROVED (reviewer: claude)",
 "in": 2, "cached": 54082, "out": 1922,   // reviewer-reported token burn
 "cost_usd": 0.4788, "duration_ms": 29495,
 "model": "claude-haiku-4-5-20251001,claude-opus-5[1m]"}

Downstream consumers: ownership check (30-min window), tokens.py (gate burn), activity.py (verdicts, rounds, rhythm — prefix-anchored parse so a verdict word quoted mid-string can't flip it), digest merge queue (PRs ⋈ verdicts, with the rig → turbo-rig alias join), merge-qa (per-PR trajectory), weekly retro (REVISE defect classes). Append-only: nothing ever rewrites it.Consumidores aguas abajo: check de propiedad (ventana de 30 min), tokens.py (consumo de la compuerta), activity.py (veredictos, rondas, ritmo — parse anclado por prefijo para que una palabra de veredicto citada a mitad de cadena no lo vuelque), cola de fusión del digest (PRs ⋈ veredictos, con el join del alias rig → turbo-rig), merge-qa (trayectoria por PR), retro semanal (clases de defecto REVISE). Solo-agregar: nada lo reescribe jamás.

Hygiene details that matterDetalles de higiene que importan

--selftest: the gate gates itself--selftest: la compuerta se compuerta a sí misma

~280 lines of fixture-pinned proofs, no network: codex stream parsers (agent message last-wins, usage mapping, old schema alias tolerance); scratch-anchor round-trip; fail-closed proofs (a reviewer that exits 0 with empty output must return exactly 1, not 2; a truncated stream must fail; empty stdin must exit 2); auto-dispatch order (forced quota + fake codex must pick the codex lane — a claude-first regression would pass every other assertion while defeating the feature); definition-order pinning (a helper defined after its call site is a silent misfire — caught twice in real bugs); ownership fixtures (fresh-foreign flagged, own-fresh and stale-foreign pass); invariants extraction and hostile-scrub both fences; the cat-oracle injection e2e; deterministic-check rc contract; trap safety with a decoy directory that must survive. The platform runs a weekly gate readiness canary on top — because the reviewer lane's demonstrated failure mode is silent auth rot.~280 líneas de pruebas fijadas a fixtures, sin red: parsers de flujo codex (agent message last-wins, mapeo de uso, tolerancia a alias de esquema viejo); ida-y-vuelta del ancla de rasguño; pruebas de fallo-cerrado (un revisor que sale 0 con salida vacía debe retornar exactamente 1, no 2; un flujo truncado debe fallar; stdin vacío debe salir 2); orden del auto-despacho (cuota forzada + codex falso debe elegir el carril codex — una regresión claude-primero pasaría todas las demás aserciones mientras derrota la función); fijado del orden de definición (un helper definido tras su punto de llamada es un disparo silencioso — atrapado dos veces en bugs reales); fixtures de propiedad (ajeno-fresco marcado, propio-fresco y ajeno-rancio pasan); extracción de invariantes y lavado hostil de ambas cercas; la inyección e2e del oráculo-cat; contrato rc del check determinista; seguridad de traps con un directorio señuelo que debe sobrevivir. La plataforma corre encima un canario semanal de disposición de la compuerta — porque el modo de falla demostrado del carril revisor es la rotación silenciosa de auth.

04Isolation, onboarding & the planes04Aislamiento, onboarding y los planos

Worktrees so parallel writers can't collide; a 30-second onboarding script; a bootstrap that turns any machine into a rig plane; secrets encrypted at rest; heavy work shipped off-box.Worktrees para que los escritores en paralelo no colisionen; un script de onboarding de 30 segundos; un bootstrap que convierte cualquier máquina en un plano del rig; secretos cifrados en reposo; el trabajo pesado enviado fuera de la caja.

scripts/wt.sh41 lines · worktrees41 líneas · worktrees

The documented cure for the multi-agent merge tax: parallel writers in separate worktrees, on branches, touching disjoint files. wt.sh <name> [base] creates <repo>/.worktrees/<name> + branch <name> from main (falls back to master), prints the path, and narrates the loop: build there → gate the diff → PR → human merges → wt.sh --clean <name>. Worktree names are unique leaf names — which is exactly what the gate's ownership check keys on, so isolation and ownership are the same mechanism. --list delegates to git worktree list.La cura documentada para el impuesto de fusión multi-agente: escritores en paralelo en worktrees separados, sobre ramas, tocando archivos disjuntos. wt.sh <name> [base] crea <repo>/.worktrees/<name> + la rama <name> desde main (cae a master si hace falta), imprime la ruta y narra el bucle: construir ahí → compuertar el diff → PR → el humano fusiona → wt.sh --clean <name>. Los nombres de worktree son nombres hoja únicos — exactamente aquello sobre lo que keya el check de propiedad de la compuerta, así que aislamiento y propiedad son el mismo mecanismo. --list delega en git worktree list.

Field gotcha: --clean removes the branch as well as the worktree — branches you want to keep are cleaned by hand. And since the gate compares against LOCAL main, merge-day discipline is pull --ff-only before gating from a worktree.Gotcha de campo: --clean elimina la rama además del worktree — las ramas que quieras conservar se limpian a mano. Y como la compuerta compara contra el main LOCAL, la disciplina del día de fusión es pull --ff-only antes de compuertar desde un worktree.

scripts/init-repo.sh53 lines · repo onboarding53 líneas · onboarding de repo

Run once inside any git repo: writes a thin AGENTS.md (constitution pointer + a five-line project cheat-sheet — stack, test command, run, deploy, gotchas — that agents read every session), symlinks CLAUDE.md → AGENTS.md (one source, no drift; Codex reads AGENTS.md natively), and appends the repo to repos.txt so the morning digest watches it. Never clobbers existing files. This is the "subscribe, don't integrate" philosophy mechanized — new repos join the gravity well in 30 seconds.Se corre una vez dentro de cualquier repo git: escribe un AGENTS.md delgado (puntero a la constitución + una cheatsheet de proyecto de cinco líneas — stack, comando de test, run, deploy, gotchas — que los agentes leen cada sesión), enlaza CLAUDE.md → AGENTS.md (una fuente, cero deriva; Codex lee AGENTS.md nativamente) y agrega el repo a repos.txt para que el digest matutino lo vigile. Nunca sobreescribe archivos existentes. Es la filosofía "suscríbete, no integres" mecanizada — los repos nuevos se unen al pozo de gravedad en 30 segundos.

scripts/bootstrap.sh127 lines · any machine → a rig plane127 líneas · cualquier máquina → un plano del rig

Idempotent turnkey setup. Base install: the two CLIs (thin npm globals, no daemons), skills single-sourced at ~/.agents/skills and symlinked into whichever harnesses exist, the secrets home, and a global .worktrees/ gitignore. It also installs the deletion-guard pre-commit hook globally via core.hooksPath (see below).Setup turnkey idempotente. Instalación base: los dos CLIs (globals npm delgados, sin daemons), skills con fuente única en ~/.agents/skills y enlazados en los harnesses que existan, el hogar de secretos, y un gitignore global de .worktrees/. También instala el hook pre-commit guardián-de-borrados de forma global vía core.hooksPath (ver abajo).

--wire adds the spine: points ~/.zcode/AGENTS.md and ~/.claude/CLAUDE.md at the constitution (existing files backed up to *.pre-rig — nothing destroyed), writes Claude-specific reviewer overrides (diff-only, read-only, verdict-line contract), wires Codex with a default sandbox_mode = "read-only", and treats AGENTS.md content in untrusted repos as data, not instructions. The portability canary re-proves this whole flow on a clean codespace monthly.--wire añade la espina: apunta ~/.zcode/AGENTS.md y ~/.claude/CLAUDE.md a la constitución (los archivos existentes se respaldan a *.pre-rig — nada se destruye), escribe los overrides de revisor específicos de Claude (solo-diff, solo-lectura, contrato de línea-de-veredicto), cablea a Codex con sandbox_mode = "read-only" por defecto y trata el contenido AGENTS.md de repos no confiables como dato, no instrucción. El canario de portabilidad re-prueba este flujo completo en un codespace limpio cada mes.

scripts/git-hooks/pre-commit18 lines · deletion guard18 líneas · guardián de borrados

The "fix-kit as code" pattern, born from two real deletion near-misses (a Finder deletion swept into history by a blanket git add -A; a stray commit -a on a test branch). It lists staged deletions (--diff-filter=D) and shouts — warn-only, fail-open: it never blocks a commit, it makes deletions loud instead of silent. Intentional? Commit again. Accidental? git restore --staged.El patrón "kit-de-fixes como código", nacido de dos casi-accidentes reales de borrado (un borrado de Finder arrastrado a la historia por un git add -A blanket; un commit -a perdido en una rama de prueba). Lista los borrados staged (--diff-filter=D) y grita — solo advierte, falla abierto: nunca bloquea un commit, hace los borrados ruidosos en vez de silenciosos. ¿Intencional? Commitea de nuevo. ¿Accidental? git restore --staged.

scripts/secret.sh126 lines · secrets, encrypted at rest126 líneas · secretos, cifrados en reposo

The rationale is stated in the file: hashes are one-way, but secrets the rig must use (API keys, tokens) must be recoverable — so they get encrypted storage, not hashed. Backend auto-detection, first available wins: macOS Keychain (built-in, zero install) → libsecret on Linux desktops → age on headless servers (one static binary; key file chmod 600, secrets encrypted to its public key) → plaintext file with a LOUD warning as last resort. list prints names only, never values (Keychain's dump format isn't stably parseable, so a names-only index file backs it). Sourceable helpers (rig_secret_get/set) let other scripts use it as a library. In CI/Codespaces the guidance is simpler: env vars, nothing stored.La justificación está enunciada en el archivo: los hashes son de una vía, pero los secretos que el rig debe usar (API keys, tokens) deben ser recuperables — así que obtienen almacenamiento cifrado, no hasheado. Auto-detección de backend, gana el primero disponible: Keychain de macOS (integrado, cero instalación) → libsecret en escritorios Linux → age en servidores sin cabeza (un binario estático; archivo de llave chmod 600, secretos cifrados a su llave pública) → archivo plano con un aviso RUIDOSO como último recurso. list imprime solo nombres, jamás valores (el formato dump del Keychain no es establemente parseable, así que lo respalda un archivo índice de solo-nombres). Helpers sourceables (rig_secret_get/set) dejan a otros scripts usarlo como librería. En CI/Codespaces la guía es más simple: variables de entorno, nada almacenado.

scripts/remote.sh344 lines · execution plane, mechanized344 líneas · plano de ejecución, mecanizado

"The cockpit stays thin; the cloud sweats only when it must." ensure <tool> -- <cmd> runs the command locally if the tool exists, else fires a throwaway remote box to run it; run -- forces the remote lane. Two lanes: gh Codespaces (free tier; create → ssh → sync → run → delete) and Google Cloud Shell (free weekly quota; persists 5GB home). Every invocation deletes its own box even on failure — no orphaned state, ever."La cabina se mantiene flaca; la nube suda solo cuando debe." ensure <tool> -- <cmd> corre el comando local si la herramienta existe, si no dispara una caja remota desechable para correrlo; run -- fuerza el carril remoto. Dos carriles: gh Codespaces (free tier; create → ssh → sync → run → delete) y Google Cloud Shell (cuota semanal gratis; persiste un home de 5GB). Cada invocación borra su propia caja incluso en fallo — estado huérfano, jamás.

Secret hygiene is enforced mechanically: the upload sync excludes .env*, *.pem, *.key, .npmrc, .aws, .ssh, .gnupg, *.kdbx, secrets* (with dual tar-variant patterns), and warns when exclusion actually dropped something — the no-secrets-up claim is checked, not assumed. cleanup-stale reaps rig boxes older than a day.La higiene de secretos se aplica mecánicamente: el sync de subida excluye .env*, *.pem, *.key, .npmrc, .aws, .ssh, .gnupg, *.kdbx, secrets* (con patrones duales por variante de tar) y avisa cuando la exclusión de verdad soltó algo — el reclamo sin-secretos-arriba se verifica, no se asume. cleanup-stale recoge las cajas del rig con más de un día.

remote.sh — the cockpit stays thin; the cloud sweatsonly when it mustmode?ensure run --tool presentlocally?run localthrowaway box:codespace |cloudshellcreate → sync workdir IN(secret-shaped filesexcluded+ warned) → run → sync outDELETE THE BOX —even on failurecleanup-stale reaps >1d boxesalways remoteyesno / forcedremote lane
scripts/workspace.sh178 lines · session homes178 líneas · hogares de sesión

Fixes deliverable scatter (QA reports next to tax PDFs, one-off HTML at top level) with a convention plus a pointer, not a daemon: <workspace>/turbo-rig/sessions/YYYY-MM-DD-<slug>/ is the session's output home, and active-session is a pointer file any later shell can read. file <name> resolves output paths (creating nested dirs) and refuses traversal — ../, absolute paths, and a/../b all exit 2, and the resolved target must lexically stay inside the session dir. Slugs collapse runs (re-init same day+slug reuses the dir); list shows sizes with the active session starred. Non-goals are explicit: it never sweeps or moves existing files — the workspace holds personal files, and curation stays a human/agent decision. A sibling convention (in the constitution, not this script): turbo-rig/inputs/ is the human→rig hand-off box — sessions check it first, never modify originals.Corrige la dispersión de entregables (reportes QA junto a PDFs de impuestos, HTML suelto en el nivel superior) con una convención más un puntero, no un daemon: <workspace>/turbo-rig/sessions/YYYY-MM-DD-<slug>/ es el hogar de salida de la sesión, y active-session es un archivo puntero que cualquier shell posterior puede leer. file <name> resuelve rutas de salida (creando directorios anidados) y rechaza traversal — ../, rutas absolutas y a/../b salen con 2, y el destino resuelto debe quedarse léxicamente dentro del directorio de sesión. Los slugs colapsan corridas (re-init mismo día+slug reutiliza el dir); list muestra tamaños con la sesión activa esterlina. Los no-objetivos son explícitos: jamás barre ni mueve archivos existentes — el workspace guarda archivos personales y la curación queda como decisión humano/agente. Una convención hermana (en la constitución, no en este script): turbo-rig/inputs/ es la bandeja de entrega humano→rig — las sesiones la revisan primero, jamás modifican originales.

scripts/claude-flow-aliases.sh652 lines · legacy, quarantined652 líneas · legado, en cuarentena

The 689 cf-*/swarm/neural aliases from the pre-rig claude-flow era, extracted from a .zshrc that carried them duplicated up to 7×. Not deleted — Law 8 subtracts, but auditable history stays — just moved out of every shell's path. Load on demand with source. Its existence documents the subtraction: the swarm layer it served was cut because native harness features replaced every part of it.Los 689 aliases cf-*/swarm/neural de la era claude-flow pre-rig, extraídos de un .zshrc que los llevaba duplicados hasta 7×. No borrados — la Ley 8 sustrae, pero la historia auditable se queda — solo movidos fuera del PATH de cada shell. Se cargan a demanda con source. Su existencia documenta la sustracción: la capa de enjambre a la que servía fue cortada porque las funciones nativas del harness reemplazaron cada parte de ella.

05Observability — tokens.py · activity.py · digest.sh05Observabilidad — tokens.py · activity.py · digest.sh

Two live dashboards and one morning gatherer. One answers "what did the models burn?", the other "what did the rig DO?", and the digest turns both into the day's briefing.Dos dashboards vivos y un recolector matutino. Uno responde "¿qué quemaron los modelos?", el otro "¿qué HIZO el rig?", y el digest convierte ambos en el informe del día.

scripts/tokens.py1,576 lines · the burn dashboard1,576 líneas · el dashboard de consumo

Read-only aggregation over every provider's native telemetry, one adapter each:Agregación de solo-lectura sobre la telemetría nativa de cada proveedor, un adaptador por cada uno:

  • zcode — ~/.zcode/cli/db/db.sqlite, table model_usage: per-request rows (epoch-ms UTC), joined to session titles for the "where did my tokens go" panel. Title-generation background calls excluded by query_source.zcode — ~/.zcode/cli/db/db.sqlite, tabla model_usage: filas por-request (epoch-ms UTC), unidas a títulos de sesión para el panel "a dónde se fueron mis tokens". Las llamadas de fondo de generación de títulos se excluyen por query_source.
  • claude — ~/.claude/projects/*/*.jsonl: assistant-message usage envelopes only; synthetic/error lines skipped; deduplicated on (requestId, message.id) keeping the fullest envelope — forked/resumed sessions rewrite prior turns into new files, and dedup is what makes re-reads non-double-counting. Files unmodified for >7d can't hold window rows and are skipped by mtime.claude — ~/.claude/projects/*/*.jsonl: solo sobres de uso de mensajes-asistente; líneas sintéticas/de error se saltan; deduplicados por (requestId, message.id) conservando el sobre más completo — las sesiones bifurcadas/reanudadas reescriben turnos previos en archivos nuevos, y el dedup es lo que vuelve las re-lecturas no-doble-contadoras. Los archivos sin modificar por >7d no pueden sostener filas de ventana y se saltan por mtime.
  • codex — ~/.codex/sessions/**/rollout-*.jsonl: token_count events where last_token_usage is the per-turn delta (windowable); free-tier null usage becomes an explicit coverage note, not a silent zero.codex — ~/.codex/sessions/**/rollout-*.jsonl: eventos token_count donde last_token_usage es el delta por turno (ventaneable); el uso null del free tier se vuelve nota de cobertura explícita, no un cero silencioso.
  • gate — the gate log (review burn).gate — el log de la compuerta (consumo de revisión).
  • quota — live plan utilization via the same Keychain+endpoint pattern as the gate.quota — utilización viva del plan vía el mismo patrón Keychain+endpoint que la compuerta.

Convention notes that matter for correctness: the gate log's timestamps are LOCAL naive; zcode is epoch-ms UTC; claude/codex in-file timestamps are ISO UTC — each adapter normalizes before windows are applied. Non-goals are pinned in the header: no cost tables, no daemon, no config plugins, no history DB, no alerting — "if it isn't telemetry, it isn't this tool." --watch gives a 2s live view with incremental file-offset scanning; --selftest runs golden-fixture tests per adapter; --cap turns a plan limit into a utilization bar. Exit 2 = a provider rendered degraded, so pipeline consumers can tell.Notas de convención que importan para la corrección: los timestamps del log de la compuerta son LOCALES ingenuos; zcode es epoch-ms UTC; los timestamps in-file de claude/codex son ISO UTC — cada adaptador normaliza antes de aplicar ventanas. Los no-objetivos están fijados en el encabezado: sin tablas de costos, sin daemon, sin plugins de config, sin BD de historia, sin alertas — "si no es telemetría, no es esta herramienta". --watch da una vista viva de 2s con escaneo incremental por offset de archivo; --selftest corre pruebas de fixture dorada por adaptador; --cap convierte un límite de plan en una barra de utilización. Exit 2 = un proveedor quedó degradado, para que los consumidores de pipeline lo distingan.

scripts/activity.py419 lines · the motion dashboard419 líneas · el dashboard de movimiento

Drawn purely from the gate log. Verdict parsing is prefix-anchored (GATE: APPROVED/GATE: REVISE at line start) — a verdict word appearing mid-string (quoted history, hostile text) can never flip the parse, and anything unrecognized fails closed to ?. Worktree lane names fold into repo families (ancuria-* → ancuria). The interesting derived metric is rounds: gate runs per (repo, target, day) — how hard each task-day looped, with the worst offender named ("34 — rig main..HEAD"). A day×hour grid exposes the operating rhythm (including whether the night sweep ran); median/average/slowest review latency and total spend round it out. Same CLI shape as tokens.py (windows, watch, json, selftest) — the two dashboards are deliberate siblings.Dibujado puramente del log de la compuerta. El parse de veredictos es anclado por prefijo (GATE: APPROVED/GATE: REVISE al inicio de línea) — una palabra de veredicto a mitad de cadena (historia citada, texto hostil) jamás puede voltear el parse, y lo no reconocido falla cerrado a ?. Los nombres de carril worktree se pliegan en familias de repo (ancuria-* → ancuria). La métrica derivada interesante es rondas: corridas de compuerta por (repo, target, día) — qué tan duro loopeó cada día-tarea, con el peor ofensor nombrado ("34 — rig main..HEAD"). Una cuadrícula día×hora expone el ritmo operativo (incluido si corrió el barrido nocturno); latencia mediana/promedio/más-lenta de revisión y gasto total la completan. Misma forma de CLI que tokens.py (ventanas, watch, json, selftest) — los dos dashboards son hermanos deliberados.

scripts/digest.sh614 lines · the morning inputs gatherer614 líneas · el recolector de insumos matutinos

Runs at 08:00 weekdays (scheduled automation); gathers mechanical inputs into memory/inbox/<date>.md and a second automation prepends a ≤30-line "## Today" narrative on top. Sections, each a small parser (all fixture-tested):Corre a las 08:00 días hábiles (automatización programada); reúne los insumos mecánicos en memory/inbox/<date>.md y una segunda automatización antepone encima una narrativa "## Today" de ≤30 líneas. Secciones, cada una un parser pequeño (todos probados con fixtures):

  • Agent usage — 7-day gate burn (runs, verdict split, tokens, API-equivalent cost, top-5 targets by cost), Claude session burn outside the gate, codex dormancy, and live plan-quota lines with reset times.Uso de agentes — consumo de compuerta a 7 días (corridas, split de veredictos, tokens, costo API-equivalente, top-5 targets por costo), consumo de sesión de Claude fuera de la compuerta, dormancia de codex y líneas vivas de cuota-de-plan con tiempos de reset.
  • Per-repo snapshot — for each repos.txt entry: local repos report branch/dirty-count/last-commit; GitHub slugs list open PRs and issues.Instantánea por repo — por cada entrada de repos.txt: los repos locales reportan rama/conteo-sucio/último-commit; los slugs de GitHub listan PRs e issues abiertos.
  • Merge queue — open PRs across all slugs ⋈ gate-log verdicts, answering "ready to merge?": GATED: APPROVED / REVISE outstanding / UNGATED ← review.sh --pr N. The join normalizes repo names (the gate logs the clone dir; the founder's turbo-rig clone is ~/rig — the alias is pinned by fixtures after it bit once). A failed gh query shortens the queue loudly, never silently.Cola de fusión — PRs abiertos de todos los slugs ⋈ veredictos del gate-log, respondiendo "¿listo para fusionar?": GATED: APPROVED / REVISE pendiente / UNGATED ← review.sh --pr N. El join normaliza nombres de repo (la compuerta loguea el dir del clon; el clon turbo-rig del fundador es ~/rig — el alias lo fijan fixtures después de que mordió una vez). Una query gh fallida acorta la cola en voz alta, jamás en silencio.
  • Merged PRs (7d) — each with its gate rounds, REVISE count, model, token breakdown, cost.PRs fusionados (7d) — cada uno con sus rondas de compuerta, conteo REVISE, modelo, desglose de tokens, costo.
  • Site liveness — every sites.txt URL curl'd: UP (2xx/3xx) or DOWN ← check this.Vida de sitios — cada URL de sites.txt con curl: UP (2xx/3xx) o DOWN ← revisa esto.
  • Codespace hygiene — stale boxes >7d flagged for deletion; rows with unknown timestamps are reported as unknown, never silently skipped (a skip would read as "all clean").Higiene de codespaces — cajas rancias >7d marcadas para borrado; las filas con timestamp desconocido se reportan como desconocidas, jamás saltadas en silencio (un salto se leería como "todo limpio").
  • Repo hygiene — gap-only list of repos missing LICENSE/description/homepage/topics, archived-filtered. Metadata is untrusted and travels JSON end-to-end through one resilient decoder — never flattened to TSV (a tab in a description would shift records); junk lines and truncated chunks are skipped and counted ("completeness unknown").Higiene de repos — lista de solo-huecos de repos sin LICENSE/description/homepage/topics, filtrada de archivados. Los metadatos son no confiables y viajan JSON de-punta-a-punta por un decodificador resiliente — jamás aplanados a TSV (una pestaña en una description movería registros); las líneas basura y los chunks truncados se saltan y se cuentan ("completitud desconocida").
  • Inbox backlog + rig repo activity.Resaca de bandeja + actividad del repo del rig.
digest.sh — mechanical inputs → one inbox file (everyparser fixture-tested)gate-log.jsonl~/.claude/projects/*.jsonl~/.codex/sessions/**gh api (PRs ·quota)git repos(repos.txt)sites.txt ·codespacesone resilient JSON decoder(raw_decode) —junk/truncation skipped ANDcounted;repo names normalized (rig →turbo-rig)usage rolls: gate burn ·claude-outside-gate ·quotasections: usage · per-repo · merge queue(PRs ⋈ gate-log → GATED / REVISE / UNGATED)·merged PRs · site liveness · codespacehygiene · repo hygiene (gap-only) · inboxbacklogmemory/inbox/.md+ '## Today' prependeda failed gh query shortens the queue LOUDLY, never silently

06QA machinery — qa-report.sh · merge-qa.sh · configs/06Maquinaria QA — qa-report.sh · merge-qa.sh · configs/

Proofs before prophets, mechanized: QA reports assemble what is provable — fresh live evidence — and leave judgment to explicitly-marked agent sections.Pruebas antes que profetas, mecanizado: los reportes QA ensamblan lo demostrable — evidencia viva fresca — y dejan el juicio a secciones de agente explícitamente marcadas.

scripts/qa-report.sh420 lines · deterministic QA gatherer420 líneas · recolector QA determinista

Given a repo, a commit range, a base URL, and a config (a bash snippet — see below), it emits a markdown QA report where every evidence row ran at generation time or says so:Dado un repo, un rango de commits, una URL base y una config (un snippet bash — ver abajo), emite un reporte QA en markdown donde cada fila de evidencia corrió al momento de generación o lo dice:

  • Build/merge table — git log over the range, each commit joined to its PR number via the repo's merged-PR list.Tabla build/fusión — git log sobre el rango, cada commit unido a su número de PR vía la lista de PRs fusionados del repo.
  • Environment health — configured paths curl'd; 2xx/3xx = healthy (a 307-to-login on gated pages is by design); auth-prefixed paths without a cookie jar skip with the reason stated — "a 307 proves the gate, not the page".Salud del entorno — rutas configuradas con curl; 2xx/3xx = sano (un 307-a-login en páginas gated es por diseño); las rutas con prefijo de auth sin cookie jar se saltan con la razón enunciada — "un 307 prueba la compuerta, no la página".
  • API evidence matrix — rows like GET /api/listings?bedrooms=2&limit=1|total=33 parsed into method/path/check; checks verdict live: status=, total=<want> (pinned), bare total (record-only baseline — a 200 body that isn't JSON fails closed rather than fabricating a green row), present=/absent= substrings. A network failure (status 000) is a FAIL row, never a PASS on absent-checks.Matriz de evidencia API — filas como GET /api/listings?bedrooms=2&limit=1|total=33 parseadas en método/ruta/check; los checks verifican en vivo: status=, total=<want> (fijado), total simple (línea base solo-registro — un cuerpo 200 que no es JSON falla cerrado en vez de fabricar una fila verde), substrings present=/absent=. Un fallo de red (status 000) es fila FAIL, jamás un PASS por checks-ausentes.
  • Client bundle labels — for SPA surfaces that never appear in raw HTML: fetch a real page, extract JS chunk URLs across Next.js/_nuxt/Vite families, fetch every chunk, scan for labels that must be present/absent. A page with zero chunks is a SETUP error, never fabricated verdicts.Etiquetas del bundle cliente — para superficies SPA que jamás aparecen en HTML crudo: trae una página real, extrae URLs de chunks JS entre familias Next.js/_nuxt/Vite, trae cada chunk, escanea etiquetas que deben estar presentes/ausentes. Una página con cero chunks es error de SETUP, jamás veredictos fabricados.
  • AGENT sections — per-ticket test cases, known issues, acceptance scope: emitted as structured templates with no verdict until a human or live re-run provides one.Secciones AGENT — casos de prueba por ticket, problemas conocidos, alcance de aceptación: emitidas como plantillas estructuradas sin veredicto hasta que un humano o una re-corrida en vivo lo provea.

Exit precedence is explicit: SETUP(2) outranks FAIL(1) — a broken harness is not a verdict; exit 4 = nothing executed (all rows skipped), which can never read as green. The secrets law holds: the cookie file is referenced by path only; raw response bodies are never embedded. A "re-execution quick reference" block prints the exact curl lines so any row can be re-proven by hand. The selftest spins a local HTTP fixture server and runs the whole script e2e against it offline.La precedencia de salidas es explícita: SETUP(2) supera a FAIL(1) — un harness roto no es un veredicto; exit 4 = nada se ejecutó (todas las filas saltadas), que jamás puede leerse verde. La ley de secretos se mantiene: el archivo de cookies se referencia solo por ruta; los cuerpos de respuesta crudos jamás se incrustan. Un bloque de "referencia rápida de re-ejecución" imprime las líneas curl exactas para que cualquier fila se pueda re-probar a mano. El selftest levanta un servidor HTTP fixture local y corre el script completo e2e contra él, offline.

qa-report.sh — the evidence-row pipeline (per configrow)row: "[auth:]METHOD/path|check"parse_row shapeok?FAIL row:unparseable(fail-closed)auth row AND nocookie jar?SKIP (counted,stated)fetch: status 000?(network/timeout)FAIL row: requestfailed(never a PASS onabsent=)apply_check: status=… ·total= · total(record-only — non-JSON 200 FAILs)·present=… · absent=… · unknown →FAILPASS / FAIL / RECORD→ bump countersexit precedence: SETUP (2) > FAIL (1) >all-skipped (4) > green (0)a broken harness is not a verdict ·nothing-executed is not greennoyesyesnoyesno
scripts/merge-qa.sh384 lines · merge-triggered QA reports384 líneas · reportes QA disparados-por-fusión

The trigger is a merge. For every PR merged since the last run (per-repo watermark in ~/.local/state/turbo-rig/merge-qa.state; first run backfills 7 days), it assembles the QA record from three sources: (1) identity via gh — number, title, author, merge SHA, files; (2) the gate record — every gate-log run for that PR, with worktree-prefix attribution (ancuria-* rows join to ancuria; an alias map handles rig→turbo-rig) and verdict trajectory; (3) live checks — the repo's configs/<repo>-qa.conf re-run via qa-report against the deployed app (auth rows skip cleanly when the automation carries no cookie).El disparador es una fusión. Por cada PR fusionado desde la última corrida (watermark por repo en ~/.local/state/turbo-rig/merge-qa.state; la primera corrida retrocede 7 días), ensambla el registro QA de tres fuentes: (1) identidad vía gh — número, título, autor, SHA de fusión, archivos; (2) el registro de la compuerta — cada corrida del gate-log para ese PR, con atribución por prefijo de worktree (las filas ancuria-* se unen a ancuria; un mapa de alias maneja rig→turbo-rig) y trayectoria de veredictos; (3) checks en vivo — el configs/<repo>-qa.conf del repo re-corrido vía qa-report contra la app desplegada (las filas con auth se saltan limpio cuando la automatización no lleva cookie).

Reports land in qa/<repo>/<date>-pr<N>.md plus a row in qa/INDEX.md — git-versioned, so QA history rides the repo. Verdict logic: FLAGGED if the final gate verdict was REVISE/unparseable, live checks failed, or the live harness errored; CLEAN otherwise — with "UNGATED" as a visible note, not a flag (branch-mode gating evidence lives in PR gate comments). One subtlety worth calling out: at the 100-PR fetch limit the watermark holds at the batch-oldest instead of advancing — anything stranded beyond the limit gets re-covered next run rather than silently skipped.Los reportes aterrizan en qa/<repo>/<date>-pr<N>.md más una fila en qa/INDEX.md — versionados en git, así la historia QA viaja en el repo. Lógica de veredicto: FLAGGED si el veredicto final de la compuerta fue REVISE/ineparseable, checks en vivo fallidos o el harness vivo erró; CLEAN en caso contrario — con "UNGATED" como nota visible, no bandera (la evidencia de compuerta en modo rama vive en los comentarios de compuerta del PR). Una sutileza que vale señalar: en el límite de 100 PRs del fetch, el watermark se sostiene en el más viejo del lote en vez de avanzar — lo varado más allá del límite se re-cubre la corrida siguiente en lugar de saltarse en silencio.

merge-qa.sh — the merge is the triggertrigger: run(--all | --repo)state_get watermark(first run: 168 hbackfill)gh pr list --statemergedsince watermarkidentity: number ·titleauthor · SHA · filesgate-log join:worktree-prefixattribution +rig→turbo-rigalias → verdict trajectorylive checks:configs/-qa.confvia qa-report (auth rowsskip)no conf → 'notconfigured'final REV/unparseable orlive FAIL / harnesserror?FLAGGED (exit 1)report says whyCLEAN — merged,gate-approved,live green (UNGATED =note)qa//-prN.md+ INDEX.md rowwatermark: advance to newest — or HOLD atbatch-oldest at the 100-PR limitnoneyesnoeither
configs/*.confper-product QA matricesmatrices QA por producto

Bash snippets consumed by qa-report — e.g. ancuria-qa.conf: health paths for public and auth'd surfaces, an API matrix covering price bands, dimension filters, keyword∩dimension intersections, and a stated verdict policy: structural checks pinned and verdict live; listing totals record-only by default "counts drift with real data — do not fail a sweep on drift," pinned only right after a release. No secrets, ever — the header says so and the harness enforces it.Snippets bash consumidos por qa-report — p.ej. ancuria-qa.conf: rutas de salud para superficies públicas y con auth, una matriz API cubriendo bandas de precio, filtros de dimensión, intersecciones palabra-clave∩dimensión, y una política de veredicto enunciada: checks estructurales fijados y veredicto en vivo; totales de listados solo-registro por defecto — "los conteos derivan con datos reales — no fails un barrido por deriva" — fijados solo justo tras un release. Sin secretos, jamás — el encabezado lo dice y el harness lo aplica.

07scripts/railway-pr-env-sweep.py

A self-healing control loop for Railway preview environments — and a precise little state machine about when it's allowed to touch a database variable.Un lazo de control auto-reparante para entornos preview de Railway — y una pequeña máquina de estados precisa sobre cuándo le es permitido tocar una variable de base de datos.

The problem: Railway PR environments fork production's variables, so they inherit DATABASE_URL with the private hostname postgres.railway.internal — which resolves, per-environment, to that env's own empty Postgres. The app boots, migrations run, and every login 401s against zero users. Rather than per-repo CI wiring, this one central script sweeps every configured project's PR environments and repoints DATABASE_URL at the live database's public endpoint (Railway auto-redeploys on variable change; the script never triggers deploys). Idempotent and safe on a ~30-minute schedule — it also catches Railway's late variable-fork overwrite that one-shot wiring misses.El problema: los entornos PR de Railway bifurcan las variables de producción, así que heredan DATABASE_URL con el hostname privado postgres.railway.internal — que resuelve, por entorno, al propio Postgres vacío de ese env. La app arranca, corren las migraciones y cada login da 401 contra cero usuarios. En lugar de cableado de CI por repo, este único script central barre los entornos PR de cada proyecto configurado y repunta DATABASE_URL al endpoint público de la base viva (Railway auto-re-despliega al cambiar una variable; el script jamás dispara deploys). Idempotente y seguro en calendario de ~30 minutos — también atrapa la sobre-escritura tardía de variables-fork de Railway que el cableado de un solo tiro se pierde.

The logic that earns its keep — three-way state classification per environment, never hardcoded per branch:La lógica que se gana su sueldo — clasificación de estado en tres vías por entorno, jamás hardcodeada por rama:

Before any destructive consequence, backup freshness is checked lazily (only paid when some env is actually env-local): the per-env R2 dump age, fetched with R2 creds pulled from the Railway source service — and every distinct way freshness can be unknown gets its own named reason ("misconfiguration must not hide behind 'unavailable'"). Pre-rewire env-local data gets an explicit "orphaned by this rewire — its dump is the only surviving copy" note. Operational hygiene: the API 403s python's default User-Agent (custom UA), credential-bearing URLs are never printed (only hostnames), the Railway token is stripped from the child environment so the backup tool can't act with the sweep's authority, one bad env never aborts the project's others — and an errored env marks the run "changed" so an incomplete sweep can never report a clean no-op. The selftest mocks the GraphQL transport and proves the write path issues exactly one correct upsert.Antes de cualquier consecuencia destructiva, la frescura del respaldo se verifica perezosamente (solo se paga cuando algún env es de verdad env-local): la edad del dump R2 por env, traída con credenciales R2 jaladas del servicio fuente de Railway — y cada forma distinta en que la frescura puede ser desconocida recibe su propia razón nombrada ("una mala configuración no debe esconderse tras 'no disponible'"). Los datos env-local pre-rewire reciben una nota explícita de "huérfanos por este rewire — su dump es la única copia superviviente". Higiene operativa: la API le da 403 al User-Agent default de python (UA custom), las URLs con credenciales jamás se imprimen (solo hostnames), el token de Railway se desprende del entorno hijo para que la herramienta de respaldo no pueda actuar con la autoridad del barrido, un env malo jamás aborta a los demás del proyecto — y un env con error marca la corrida como "changed" para que un barrido incompleto jamás reporte un no-op limpio. El selftest simula el transporte GraphQL y prueba que la ruta de escritura emite exactamente un upsert correcto.

railway-pr-env-sweep.py — per PR-environment statemachineread DATABASE_URL+ PR_ENV_DB_PINclassify (computed,neverhardcoded per branch):URL == live-DB URLalready wired → no-ophostname = internalfork default →REWIREpin + non-default URLdeliberate → SKIP +noteanything else =env-local datarewire = set_var DATABASE_URL→ livepublic URL (Railwayauto-redeploys;script never deploys)backup freshness (lazy — only whenenv-local): R2 dump agevia source-service creds · everyunknown mode named ·orphaned pre-rewire data flaggedwiredfork defaultoverrideother

08automations/ — the background tier08automations/ — el nivel de fondo

Nine scheduled tasks. The portability insight: platform automations are workspace- and machine-bound; what travels is the file — exact prompts plus scheduling recipes. Rebuilding the tier on a new machine is minutes, not archaeology.Nueve tareas programadas. La idea de portabilidad: las automatizaciones de plataforma viven atadas al workspace y a la máquina; lo que viaja es el archivo — prompts exactos más recetas de calendarización. Reconstruir el nivel en una máquina nueva toma minutos, no arqueología.

#TaskTareaWhenCuándoLogic in one lineLa lógica en una línea
1Morning digestDigest matutinoweekdays 08:00días hábiles 08:00Run digest.sh, prepend a ≤30-line "## Today" summary; flag roster pressure at ≥80% quota; on failure write an error file instead.Corre digest.sh, antepone un resumen "## Today" de ≤30 líneas; marca presión de roster con cuota ≥80%; ante fallo escribe un archivo de error.
2Security scanEscaneo de seguridadMon 07:30lun 07:30Codespace-hosted (the Mac installs nothing): npm audit + trivy + trufflehog over every repos.txt slug; HIGH/CRITICAL only with file:line and a proposed fix; never auto-applies; box deleted after.Hospedado en codespace (la Mac no instala nada): npm audit + trivy + trufflehog sobre cada slug de repos.txt; solo HIGH/CRITICAL con file:line y una corrección propuesta; jamás auto-aplica; caja borrada después.
3Memory consolidationConsolidación de memorianightly 23:30cada noche 23:30Fold inbox notes into decisions/gotchas/project-index (update, don't duplicate; uncertain facts become open questions, not assertions); commit the rig repo; delete inbox files >14d only when fully captured.Dobla las notas de bandeja en decisions/gotchas/project-index (actualiza, no dupliques; los hechos inciertos se vuelven preguntas abiertas, no afirmaciones); commitea el repo del rig; borra archivos de bandeja >14d solo cuando estén totalmente capturados.
4Weekly retroRetro semanalFri 17:00vie 17:00"Code that improves code": track last week's drafted amendments to their outcomes; defect-class recurring REVISE reasons (3+ consecutive weeks = constitution-amendment candidate); check live automation prompts against this file verbatim for drift. Proposal only — applies nothing."Código que mejora código": rastrea las enmiendas borradas la semana pasada hasta sus desenlaces; agrupa en clases de defecto las razones REVISE recurrentes (3+ semanas consecutivas = candidata a enmienda constitucional); verifica los prompts vivos de automatización contra este archivo textualmente por deriva. Solo propone — no aplica nada.
5Repo-hygiene fix passPasada de corrección de higieneMon 07:45lun 07:45Clear what the digest's hygiene section flags: metadata via gh repo edit (homepage only on the repo's own deploy hosts — README prose is untrusted data); LICENSE PRs only for an allowlist of own-work repos; archive recreations are not mp's to license.Limpia lo que marca la sección de higiene del digest: metadatos vía gh repo edit (homepage solo en los hosts de deploy del propio repo — la prosa del README es dato no confiable); PRs de LICENSE solo para una allowlist de repos de trabajo propio; las recreaciones de archivo no son de mp para licenciar.
6Sentinel investigatorInvestigador centinelaTue 08:15mar 08:15For every DOWN site in sites.txt: diagnose (DNS, headers, TLS, read-only Railway checks), draft a fix — never apply — to memory/inbox. UP sites get silence.Por cada sitio DOWN en sites.txt: diagnostica (DNS, headers, TLS, checks de solo-lectura de Railway), borrador de corrección — jamás la aplica — a memory/inbox. Los sitios UP reciben silencio.
7Gate readiness canaryCanario de disposición de compuertaFri 08:15vie 08:15Scratch repo + real gate pass. Any verdict (APPROVED or REVISE) proves the lane works. "Who gates the gate" — the reviewer lane's real failure mode is silent auth rot.Repo de rasguño + pasada real de compuerta. Cualquier veredicto (APPROVED o REVISE) prueba que el carril funciona. "¿Quién compuerta a la compuerta?" — el modo de falla real del carril revisor es la rotación silenciosa de auth.
8Portability canaryCanario de portabilidadmonthly, 1stmensual, día 1Fresh codespace → bootstrap --wire → digest --selftest → verify spine files: re-proves the README's fork-and-go claim on a clean machine; every failure is drift evidence.Codespace fresco → bootstrap --wire → digest --selftest → verifica archivos de espina: re-prueba el reclamo fork-and-go del README en una máquina limpia; cada fallo es evidencia de deriva.
9Nightly gate sweepBarrido nocturno de compuertadaily 01:00diario 01:00review.sh --sweep so the merge queue is gate-ready every morning; read verdicts back from PR comments (GitHub is the state machine); verdicts only — no fixes, no merges.review.sh --sweep para que la cola de fusión esté lista-para-compuerta cada mañana; lee los veredictos de vuelta desde comentarios de PR (GitHub es la máquina de estados); solo veredictos — sin correcciones, sin fusiones.
THE RHYTHM — the background tier across a weekMON07:30 security scan (codespace)07:45 hygiene fix pass08:00 digestTUE08:00 digest08:15 sentinel investigatorWED08:00 digestTHU08:00 digestFRI08:00 digest08:15 gate canary17:00 weekly retroSUN(digest weekdays only —the rig rests)every night: 23:30 consolidation ·01:00 gate sweep · monthly 1st:portability canarydigest dots cyan ○ · self-checking & maintenance lanes amber
automations/cards.shpaste cards + cross-parser selftesttarjetas para pegar + selftest entre parsers

The platform allows one automation per chat session — so onboarding the tier means pasting nine cards into nine fresh chats. cards.sh [N] prints task N's paste card, built from the README's prompt blockquote, stamped (spec: automations/README.md task N @ <sha>) — the sha records when the card was generated, so the weekly drift check compares prompt text, never shas (an unrelated README edit must not read as drift). The selftest is the clever bit: it re-extracts each expected prompt with a different parser (sed+grep) than the generator's awk — a cross-implementation comparison where a shared misparse can't pass — and structurally trims card headers/footers rather than content-filtering, so a truncated card can't slip through.La plataforma permite una automatización por sesión de chat — así que dar de alta el nivel significa pegar nueve tarjetas en nueve chats frescos. cards.sh [N] imprime la tarjeta para pegar de la tarea N, construida del blockquote de prompt del README, estampada (spec: automations/README.md task N @ <sha>) — el sha registra cuándo se generó la tarjeta, así que el chequeo semanal de deriva compara texto del prompt, jamás shas (una edición no relacionada del README no debe leerse como deriva). El selftest es la parte lista: re-extrae cada prompt esperado con un parser distinto (sed+grep) al awk del generador — una comparación entre implementaciones donde un mal-parse compartido no puede pasar — y recorta estructuralmente encabezados/pies de tarjeta en vez de filtrar contenido, así una tarjeta truncada no se cuela.

09The docs layer09La capa de docs

Manuals, design docs, runbooks, specs — each with a distinct job.Manuales, documentos de diseño, runbooks, specs — cada uno con un trabajo distinto.

FileArchivoJobTrabajo
README.mdThe public manual, quickstart-first: one-command start, the loop, growth path, any-harness usage, the GLM-free variant, client-compliance mode, token visibility, troubleshooting, FAQ, changelog.El manual público, quickstart-primero: arranque de un comando, el bucle, ruta de crecimiento, uso con cualquier harness, la variante sin GLM, modo cumplimiento-de-cliente, visibilidad de tokens, solución de problemas, FAQ, changelog.
RIG.mdThe design document: executive summary, research base (keep/cut lists with reasons), architecture, build inventory, daily operation, outstanding actions, sources.El documento de diseño: resumen ejecutivo, base de investigación (listas mantener/cortar con razones), arquitectura, inventario de construcción, operación diaria, acciones pendientes, fuentes.
RIG.htmlThe design doc as a standalone one-pager.El documento de diseño como página única independiente.
docs/UNDERSTANDING-THE-RIG.mdThe plain-language explainer — every term defined, every design choice traced to input or research.El explicador en lenguaje llano — cada término definido, cada decisión de diseño rastreada a insumo o investigación.
docs/TOKENS-MANUAL.mdManual for the dashboards.Manual de los dashboards.
docs/RUFLO-VS-RIG.md · WHY-NOT-THOSE-TOOLS.md · AGENTICS-TECHNIQUES-MAP.mdThe subtraction audit trail: wheel-by-wheel comparisons, adopt/reject decisions with triggers.La pista de auditoría de la sustracción: comparaciones rueda-por-rueda, decisiones adoptar/rechazar con disparadores.
runbooks/ ×6operating-rhythm (the daily/weekly loop), cross-review, remote-execution, swap-roster (harness swap recipe), qa-handoff, always-on-vps (night-shift variant).operating-rhythm (el bucle diario/semanal), cross-review, remote-execution, swap-roster (receta de intercambio de harness), qa-handoff, always-on-vps (variante de turno nocturno).
specs/ + templatesDelta specs for multi-day work; spec-template.md (why/delta/behavior-data-interface, builder and reviewer fields — reviewer must differ from builder) and uat.md (behavior-verification contract: the gate verifies code, UAT verifies deployed behavior).Delta specs para trabajo de varios días; spec-template.md (porqué/delta/comportamiento-datos-interfaz, campos builder y reviewer — el revisor debe distinguirse del constructor) y uat.md (contrato de verificación-de-comportamiento: la compuerta verifica código, el UAT verifica comportamiento desplegado).

10State map — where truth lives10Mapa de estado — dónde vive la verdad

Law 7: state lives on disk. The rig keeps exactly one home per kind of truth.Ley 7: el estado vive en disco. El rig mantiene exactamente un hogar por tipo de verdad.

PathRutaHoldsContieneKindTipo
~/.local/state/turbo-rig/gate-log.jsonlEvery gate run ever: verdict, tokens, cost, duration, reviewer. Append-only truth — feeds ownership, dashboards, digest, merge-QA, retro.Cada corrida de compuerta jamás hecha: veredicto, tokens, costo, duración, revisor. Verdad de solo-agregar — alimenta propiedad, dashboards, digest, merge-QA, retro.append-only loglog de solo-agregar
~/.local/state/turbo-rig/merge-qa.statePer-repo last-merge watermark for merge-QA.Watermark de última fusión por repo para merge-QA.stateestado
memory/ — decisions.md · gotchas.md · project-index.md · inbox/Cross-session facts: why decisions were made; machine facts that bite; per-project indexes; the daily inbox that consolidation folds nightly. Git-versioned, so memory rides the repo to every plane.Hechos entre sesiones: por qué se tomaron las decisiones; hechos de máquina que muerden; índices por proyecto; la bandeja diaria que la consolidación dobla cada noche. Versionado en git, así la memoria viaja en el repo a cada plano.curated memorymemoria curada
qa/ + INDEX.mdPer-PR merge-QA reports, git-versioned.Reportes merge-QA por PR, versionados en git.recordsregistros
configs/*.confPer-product QA evidence matrices.Matrices de evidencia QA por producto.config
repos.txt · sites.txtWatch lists: repos for the digest/queue; deployed URLs for liveness.Listas de vigilancia: repos para el digest/cola; URLs desplegadas para vida.config
specs/Delta specs (multi-day work) + templates.Delta specs (trabajo de varios días) + plantillas.plansplanes
backup/Legacy configs with plaintext keys — gitignored forever.Configs legados con llaves en claro — gitignored para siempre.quarantinecuarentena
~/.zcode/cli/memories/projects/<ws>/memory/Cockpit memory (GLM): a MEMORY.md one-line index (auto-loaded into every session) over typed fact files — user preferences, feedback lessons, project-lane status, references. Private to ZCode, per-workspace, not in git. Pointer-level mirror of rig state, never the canonical copy.Memoria de cabina (GLM): un índice MEMORY.md de una línea (autocargado en cada sesión) sobre archivos de hechos tipificados — preferencias de usuario, lecciones de feedback, estado de carriles de proyecto, referencias. Privada de ZCode, por workspace, fuera de git. Espejo a nivel de punteros del estado del rig, jamás la copia canónica.per-workspace memorymemoria por workspace
.worktrees/Per-task isolated worktrees (globally gitignored).Worktrees aislados por tarea (gitignored globalmente).scratchrasguño

Plus the machine-level homes bootstrap wires: ~/.agents/skills (single source, symlinked), the OS keychain via secret.sh, and the spine pointers in each harness's global instructions.Más los hogares a nivel de máquina que cablea el bootstrap: ~/.agents/skills (fuente única, enlazada), el keychain del SO vía secret.sh, y los punteros de espina en las instrucciones globales de cada harness.

The memory system — two stores, one brainEl sistema de memoria — dos almacenes, un cerebro

The rig is deliberately stateless — no daemon, no database, nothing to keep alive. That only works because memory carries the state. There are two stores with a strict division of labor, and their interop is what lets any harness, on any plane, start a fresh context and resume with full knowledge.El rig es deliberadamente sin-estado — sin daemon, sin base de datos, nada que mantener vivo. Eso solo funciona porque la memoria carga el estado. Hay dos almacenes con una división del trabajo estricta, y su interop es lo que permite a cualquier harness, en cualquier plano, arrancar un contexto fresco y reanudar con conocimiento completo.

Store A · rig memory/ (shared, canonical)Almacén A · memory/ del rig (compartido, canónico)

~/rig/memory/ — git-versioned, harness-neutral, travels to every plane with a pull. decisions.md (why the rig is the way it is), gotchas.md (machine/environment facts that bite), project-index.md (what's active, where), inbox/ (daily capture: digests, alerts, notes). The nightly 23:30 consolidation automation is the sole consolidator — it folds inbox into the durable files, commits, and pushes; git is the protocol, so VPS and Mac converge without any sync service. Law 7 pins the recall discipline: two-pass (read the index → open the 2–3 most relevant files → re-query with what you learned; one-shot retrieval misses ~2 of 3 times, field-measured) and the capture stage — before ending any session that learned something durable, append a dated line or drop a note in inbox/. "Uncaptured learning is lost learning."~/rig/memory/ — versionado en git, neutral al harness, viaja a cada plano con un pull. decisions.md (por qué el rig es como es), gotchas.md (hechos de máquina/entorno que muerden), project-index.md (qué está activo, dónde), inbox/ (captura diaria: digests, alertas, notas). La automatización de consolidación nocturna 23:30 es el único consolidador — dobla la bandeja en los archivos durables, commitea y empuja; git es el protocolo, así VPS y Mac convergen sin ningún servicio de sync. La Ley 7 fija la disciplina de recall: dos pasadas (lee el índice → abre los 2–3 archivos más relevantes → re-consulta con lo aprendido; la recuperación de una pasada falla ~2 de 3 veces, medido en campo) y la etapa de captura — antes de cerrar cualquier sesión que aprendió algo durable, agrega una línea fechada o deja una nota en inbox/. "Lo no capturado es aprendizaje perdido."

Store B · cockpit memory (GLM, private)Almacén B · memoria de cabina (GLM, privada)

ZCode keeps its own persistent memory per workspace under ~/.zcode/cli/memories/projects/<workspace>/memory/ — in this rig's main workspace that's 200+ typed fact files behind a MEMORY.md index whose one-line-per-fact entries auto-load into every session's context. Types: user (who mp is, how he works), feedback (corrections that stick — e.g. "never post re-scanned/verified claims that weren't executed this run"), project (lane status, what's closed, what's his move), reference (URLs, dashboards). It is not in git, not readable by Claude or Codex, and not canonical — it is the cockpit's operational layer: fast private recall of working style and session lessons that the other harnesses don't need.ZCode mantiene su propia memoria persistente por workspace bajo ~/.zcode/cli/memories/projects/<workspace>/memory/ — en el workspace principal de este rig son 200+ archivos de hechos tipificados tras un índice MEMORY.md cuyas entradas de una-línea-por-hecho se autocargan al contexto de cada sesión. Tipos: user (quién es mp, cómo trabaja), feedback (correcciones que pegan — p.ej. "nunca publiques reclamos de re-escaneado/verificado que no se ejecutaron en esta corrida"), project (estado del carril, qué está cerrado, qué es jugada suya), reference (URLs, dashboards). No está en git, no lo leen Claude ni Codex, y no es canónico — es la capa operacional de la cabina: recall privado y rápido del estilo de trabajo y lecciones de sesión que los otros harnesses no necesitan.

MEMORY — two stores, one brain (rig memory × cockpitmemory)any session discoversa durable fact(ZCode · Claude ·Codex)rig memory/inbox/(Law 7 capture stage:uncaptured = lost)GLM workspace memory~/.zcode/cli/memories/…MEMORY.md index + typedfilesrepo's own AGENTS.mdcheat-sheet (repofactsnever go global)nightly 23:30consolidationsole consolidator — git isthe protocol (commits +pushes)decisions.md · gotchas.md· project-index.md —git-versioned, every planerecall: two-pass (index →open 2-3 files → re-query)+ GLM index auto-loadsnext session — anyharness,any plane, freshcontextresumes with fullstaterig-canonical factcockpit factrepo factindex pre-loadsprecedence: git truth wins; cockpit files are pointersall harnesses read the same store

Division of labor (Law 8: one source of truth per concern)División del trabajo (Ley 8: una fuente de verdad por asunto)

The interop loopsLos bucles de interop

How this serves the rig as a wholeCómo esto sirve al rig en su conjunto

The two-store split is what makes Law 6 ("short fresh contexts beat long smart ones") affordable: a session can start empty because memory carries everything durable forward. The shared store stays lean — only what every harness needs — so Claude reviews and Codex gate-runs read a small, trustworthy core; the cockpit's private store absorbs the long tail of working-style and session lessons that would otherwise bloat the shared files. And because the canonical store rides git, swapping the roster (the GLM-free variant) loses nothing: the new cockpit builds its own private memory while the rig's brain arrives with the clone.La división en dos almacenes es lo que vuelve barata la Ley 6 ("contextos frescos y cortos vencen a largos e inteligentes"): una sesión puede arrancar vacía porque la memoria carga todo lo durable hacia adelante. El almacén compartido se mantiene flaco — solo lo que todo harness necesita — así las revisiones de Claude y las corridas de compuerta de Codex leen un núcleo pequeño y confiable; el almacén privado de la cabina absorbe la cola larga de estilo-de-trabajo y lecciones de sesión que de otro modo engordarían los archivos compartidos. Y como el almacén canónico viaja en git, cambiar el roster (la variante sin GLM) no pierde nada: la nueva cabina construye su memoria privada mientras el cerebro del rig llega con el clon.

11The principles that recur11Los principios que reaparecen

Read across all 20+ files, the same logic shows up everywhere. These are the rig's actual design language.Leídos a través de los más de 20 archivos, la misma lógica aparece en todas partes. Este es el lenguaje de diseño real del rig.

Fail closedFallo cerrado

Uncertainty is never a pass: unparseable verdict = REVISE, unknown git ref = error, empty diff on stdin = error, network failure = FAIL row, malformed QA row = FAIL. Every "didn't work" path lands on the red side by construction.La incertidumbre jamás es un pase: veredicto inparseable = REVISE, ref git desconocido = error, diff vacío en stdin = error, fallo de red = fila FAIL, fila QA malformada = FAIL. Cada ruta de "no funcionó" aterriza del lado rojo por construcción.

Untrusted text is dataEl texto no confiable es dato

Diffs, invariants, check output, repo metadata — everything from outside is scrubbed, fenced, prefix-anchored, or JSON-end-to-end. No untrusted line can carry a VERDICT into a prompt or comment; no metadata tab can shift a parser.Diffs, invariantes, salida de checks, metadatos de repo — todo lo de afuera se lava, se cerca, se ancla por prefijo o va JSON de-punta-a-punta. Ninguna línea no confiable puede meter un VERDICT en un prompt o comentario; ninguna pestaña de metadatos puede voltear un parser.

Proofs before prophetsPruebas antes que profetas

Deterministic checks run before LLM lanes; QA rows are fresh-by-construction or labeled; claims carry receipts (file:line, exit codes, live values). Judgment is explicitly sectioned off for humans, never smuggled into a green cell.Los checks deterministas corren antes que los carriles LLM; las filas QA son frescas-por-construcción o van etiquetadas; los reclamos llevan recibos (file:line, códigos de salida, valores vivos). El juicio se aparta explícitamente para humanos, jamás se cuela en una celda verde.

Append-only logs as truthLogs de solo-agregar como verdad

gate-log.jsonl is never rewritten — it IS the queue-ownership heartbeat, the burn ledger, the QA record source. Point-in-time views (digest) are explicitly labeled photos; the log is the live truth.gate-log.jsonl jamás se reescribe — ES el latido de propiedad de cola, el libro mayor de consumo, la fuente del registro QA. Las vistas puntuales (digest) son fotos explícitamente etiquetadas; el log es la verdad viva.

Selftest everythingSelftest a todo

Every script ships fixtures: parsers pinned against junk/truncation/hostile input, fail-closed paths proven (not assumed), cross-parser comparisons where a shared bug could hide, definition-order pinned because silent misfires shipped twice.Cada script trae fixtures: parsers fijados contra basura/truncamiento/entrada hostil, rutas de fallo-cerrado probadas (no asumidas), comparaciones entre parsers donde un bug compartido podría esconderse, orden de definición fijado porque los disparos silenciosos se enviaron dos veces.

Subtraction over additionSustraer antes que añadir

Law 8 as a standing question — "what does it replace?" — with the audit trail to prove it: frameworks cut with reasons, aliases quarantined, watch-lists with adopt-triggers instead of adoptions.La Ley 8 como pregunta permanente — "¿qué reemplaza?" — con la pista de auditoría para probarlo: frameworks cortados con razones, aliases en cuarentena, listas de vigilancia con disparadores-de-adopción en vez de adopciones.

Portability as a contractPortabilidad como contrato

Bash + python3 only, no daemons, subscription auth, prompts-not-platform for automation — proven monthly by a canary that bootstraps a clean machine and reports drift.Solo bash + python3, sin daemons, auth por suscripción, prompts-no-plataforma para automatización — probado mensualmente por un canario que hace bootstrap de una máquina limpia y reporta deriva.

Loud degradationDegradación ruidosa

Every fallback names itself: "usage unavailable, verdict stands", "completeness unknown", "skipped — no cookie", "signal absent → default". Silent fallbacks are Law-10 violations.Cada fallback se nombra a sí mismo: "uso no disponible, el veredicto se sostiene", "completitud desconocida", "saltado — sin cookie", "señal ausente → default". Los fallbacks silenciosos son violaciones de la Ley 10.

The loop, end to endEl bucle, de extremo a extremo

Morning: digest lands in the inbox (merge queue, burn, hygiene, liveness) → pick work from GitHub Issues → small task: one fresh ZCode session, plan mode if load-bearing; big: delta spec first → build in a wt.sh worktree (parallel writers on disjoint files) → review.sh --base main — deterministic checks, then a cross-family reviewer, verdict fail-closed → fix and re-gate until APPROVED → open PR (verdict posted as comment; GitHub is the state machine) → the human reviews the diff and merges → merge-qa generates the QA record → nightly: consolidation folds the day's inbox into memory; the sweep re-gates anything new. The rig notices (digest), verifies (gate), records (logs/QA), remembers (memory), and checks itself (canaries) — and never merges.Mañana: el digest aterriza en la bandeja (cola de fusión, consumo, higiene, vida) → elegir trabajo de GitHub Issues → tarea pequeña: una sesión fresca de ZCode, modo plan si es load-bearing; grande: delta spec primero → construir en un worktree de wt.sh (escritores en paralelo sobre archivos disjuntos) → review.sh --base main — checks deterministas, luego un revisor de otra familia, veredicto fallo-cerrado → corregir y re-compuertar hasta APPROVED → abrir PR (veredicto publicado como comentario; GitHub es la máquina de estados) → el humano revisa el diff y fusiona → merge-qa genera el registro QA → noche: la consolidación dobla la bandeja del día en memoria; el barrido re-compuerta lo nuevo. El rig nota (digest), verifica (compuerta), registra (logs/QA), recuerda (memoria) y se auto-chequea (canarios) — y jamás fusiona.