Introducción
La vez anterior hice que dev-orchestra revisara otra vez el cambio completo al final.
dev-orchestra es un plugin para Claude Code / Codex / Antigravity que, a partir de una petición de una sola frase, se encarga del diseño, la implementación, las pruebas, las revisiones de varias IA y las correcciones.
Aun así, “dejárselo todo desde el diseño” es un paso algo grande solo para probarlo. A menudo tengo un cambio a medio hacer en mi máquina y solo quiero que unas cuantas IA le echen un vistazo.
La revisión de dev-orchestra funciona por sí sola, aparte de las demás etapas. Esta vez explico cómo usar solo la revisión:
- Tres comandos:
review snapshot→review run→review show - Qué congela el snapshot y qué queda en
.ai/ - Las opciones que más uso, y cómo elegir
--baseal enseñar la rama de un PR - Un ejemplo de revisión de textos (artículos de este blog) en lugar de código
dev-orchestra es de código abierto y está en GitHub (licencia MIT). Si te parece útil, una estrella me haría mucha ilusión.
Entorno de prueba
| Elemento | Detalles |
|---|---|
| dev-orchestra | 1.3.0, preset standard (optimization.level con el valor por defecto balanced) |
| Revisores | claude-general (Claude Opus), codex-general (Codex CLI 0.163.0, gpt-6.1-sol), claude-security (Claude Sonnet), claude-test (Claude Sonnet) |
| Claude Code | 2.1.312 |
| Entorno | Windows 11, Git Bash, Python 3.14.7, Git 2.55.0. La configuración estaba en una carpeta aparte de la habitual (DEV_ORCHESTRA_HOME) |
Los pasos para instalar dev-orchestra están en la entrega de Claude Code y en la entrega de Codex. Aunque solo uses la revisión, la instalación y la configuración inicial son las mismas.
El objeto: una rama que añade cupones
Para el trabajo creé un pequeño paquete de Python, shopcart. En main solo hay una función que calcula el subtotal del carrito, y la rama feature/coupon añade una función de cupones.
PERCENT_OFF = {"SAVE10": 10, "SAVE20": 20}
AMOUNT_OFF = {"SAVE500": (500, 3000)} # code: (yen off, minimum subtotal)
def apply_coupon(amount, code):
"""Return the amount to pay after applying the coupon `code`."""
if code in PERCENT_OFF:
discount = amount * PERCENT_OFF[code] // 100
return amount - discount
off, minimum = AMOUNT_OFF[code]
if amount > minimum:
return amount - off
return amount
En el README escribí que “SAVE500 descuenta 500 yenes cuando el subtotal es de 3.000 yenes o más”, que “con un código desconocido el importe no cambia” y que “los códigos distinguen mayúsculas y minúsculas (a propósito)”. Es decir, en este código metí dos fallos a propósito (> debería ser >=, y un código desconocido provoca KeyError). Las 3 pruebas de cupones (5 junto con las del carrito) pasan todas.
1. Congelar el cambio (review snapshot)
Congelo el cambio desde el punto del que salió la rama (main).
dev-orchestra review snapshot --base main
Snapshot: .ai/workflows/b1627574daa6/reviews/review-target.diff
strategy: git diff main
files: 4
size: 2249 bytes (sha256 27ff110afa0b)
El snapshot es la etapa que congela en un solo archivo el diff que se va a revisar, para que todos los revisores vean lo mismo. Aunque edites los archivos después de congelarlo, el diff que ven los revisores de esa ronda no cambia. Sin --base, congela la diferencia entre el árbol de trabajo y HEAD (los cambios que aún no están en un commit). Los archivos nuevos sin commit también entran por defecto.
Lo congelado queda en .ai/.
| Archivo | Contenido |
|---|---|
review-target.diff | El diff que se enseña a los revisores |
review-target.json | El origen del diff (base, base_commit, head), la lista de archivos cambiados, las líneas añadidas y borradas, el sha256 del diff y los archivos que no se enviaron (withheld) |
state.json | El registro de este trabajo (el workflow) |
El sha256 también se escribe en el informe de cada revisor, así que después puedes comprobar que “todos vieron el mismo diff”.
En .ai/ se coloca automáticamente un .gitignore que solo contiene *, así que no acabará en un commit por descuido.
Si en la configuración pones
review.context.surrounding: enclosing, también se congelan las funciones y clases alrededor del diff y se pasan a los revisores (por defecto esnone). Los detalles están en references/reviews.md.
2. Lanzar la revisión (review run)
dev-orchestra review run
ok claude-general claude opus 3 finding(s)
1 successful, 0 failed
Consolidated: .ai/workflows/b1627574daa6/reviews/consolidated.md
note: claude-test (when: relevance) added: shopcart/__init__.py is not documentation
note: no test result recorded for this change, so the review is running unchecked. `state record test ok` before `review run` lets this stop a review of a red tree.
note: low-risk change (4 file(s), 49 line(s)): 1 reviewer instead of the full panel (claude-general). Cross-model disagreement is what a second reviewer buys; raise optimization.level or the low_risk thresholds to keep it.
Terminó en 17 segundos. Pero revisó un solo revisor. El primer note: avisa de que el revisor centrado en las pruebas, claude-test, entró como candidato porque “no es un cambio solo de documentación”. Aun así, solo se ejecutó claude-general. Como dice el último note:, con balanced un cambio pequeño que no toca rutas de alto riesgo (aquí, 4 archivos y 49 líneas) se queda con un solo revisor. En la entrega de las mediciones pasó lo mismo.
El segundo note: avisa de que no se registró el resultado de las pruebas. Si solo usas la revisión, no hace falta preocuparse. Si no quieres revisar un cambio con las pruebas en rojo, registra antes dev-orchestra state record test ok (o failed), y cuando sea failed detendrá la revisión.
3. Ver los resultados (review show)
dev-orchestra review show
El principio de la salida y el primer hallazgo fueron estos (el resto lo omito).
Source: .ai/workflows/b1627574daa6/reviews/consolidated.json
# Consolidated review
- Generated: 2026-10-29T13:19:24Z
- Iteration: 1
- Snapshot: 27ff110afa0b
- Reviewers: 1 ok / 1 total
- Coverage: round complete, change complete
- Findings: 3 (0 duplicate report(s) merged)
## Reviewers
- ok [general] claude-general / claude / opus -- 3 finding(s)
## Findings
### F1 [HIGH] correctness
- Location: `shopcart/coupon.py`:12
- Reported by: claude-general
- Possible duplicate of: none
- Triage: needs-triage
- Problem: Any code missing from `PERCENT_OFF` drops through to `AMOUNT_OFF[code]`, so an unknown code raises `KeyError`. The README says an unknown code should leave the amount unchanged.
- Impact: Checkout crashes when a user enters a mistyped or lowercase code like `save10`. The README calls out lowercase codes as invalid on purpose, so this input is expected.
- Evidence: `off, minimum = AMOUNT_OFF[code]`
- Recommended fix: Add `if code not in AMOUNT_OFF: return amount` before the lookup, or use `AMOUNT_OFF.get(code)` and return `amount` when it is `None`.
Hubo 3 hallazgos: los dos fallos que metí (F1, el KeyError; F2, el >) y F3, que señalaba que faltan pruebas de los límites. Cada hallazgo muestra la gravedad, el lugar, el problema, el impacto, la evidencia y la corrección con un formato fijo.
Con --json se obtiene lo mismo en JSON, así que también se puede pasar a otras herramientas.
4. Enseñárselo a varias IA (—only)
Si se queda en un solo revisor, no son “varias IA”. Si nombras a los revisores con --only, no se reduce su número. Sobre el mismo snapshot, añadí a los otros 3.
dev-orchestra review run --only codex-general claude-security claude-test
ok codex-general codex gpt-6.1-sol 2 finding(s)
ok claude-security claude sonnet 4 finding(s)
ok claude-test claude sonnet 5 finding(s)
3 successful, 0 failed
Consolidated: .ai/workflows/b1627574daa6/reviews/consolidated.md
note: claude-test (when: relevance) added: named by --only
note: no test result recorded for this change, so the review is running unchecked. `state record test ok` before `review run` lets this stop a review of a red tree.
Los 3 se ejecutaron en paralelo y terminaron en 19 segundos. Aunque con --only ejecutes solo una parte, el resultado consolidado (consolidated) también incluye los informes de los demás revisores sobre este snapshot. En review show aparecían 4 revisores y 14 hallazgos.
- Reviewers: 4 ok / 4 total
- Coverage: round complete, change complete
- Findings: 14 (0 duplicate report(s) merged)
Los dos fallos que metí los señalaron como fallos 3 revisores por separado, y claude-test también los mencionó en forma de “no hay ninguna prueba que lo compruebe”. Cuáles de los 14 aceptar y cuáles marcar como duplicados o rechazar lo trataré en la próxima entrega.
Si quieres enseñárselo a los 4 desde el principio, pon a los 4 en --only o sube optimization.level. También puedes nombrarlos por rol (general, security, etc.).
5. Las opciones que más uso
| Opción | Cuándo usarla |
|---|---|
--only <id o rol> | Ejecuta solo algunos revisores. También desactiva la reducción del número de revisores |
--sequential | Ejecuta los revisores uno a uno, en orden. Sirve para averiguar qué revisor se ha quedado parado |
--context "…" | Da a todos los revisores la misma premisa (“el README es la especificación”, “esto es un artículo”, etc.) |
--timeout <segundos> | Cambia el tiempo límite por revisor solo para esta ejecución |
Usadas juntas, queda así. Esta sección y la siguiente las probé en una copia del repositorio de ejemplo. El nombre del workflow lo fijé en pr-check con la variable de entorno DEV_ORCHESTRA_WORKFLOW (si no se fija, se asigna automáticamente un nombre como b1627574daa6).
dev-orchestra review run --only claude-general codex-general --sequential --timeout 300 --context "This is a pull request that adds coupons. The README is the spec."
ok claude-general claude opus 3 finding(s)
ok codex-general codex gpt-6.1-sol 2 finding(s)
2 successful, 0 failed
Consolidated: .ai/workflows/pr-check/reviews/consolidated.md
note: no test result recorded for this change, so the review is running unchecked. `state record test ok` before `review run` lets this stop a review of a red tree.
Como se ejecutaron en orden, tardó 27 segundos.
6. —base al enseñar la rama de un PR
--base main toma la diferencia entre main y el árbol de trabajo actual (strategy: git diff main). Si main ha avanzado después de crear la rama, los cambios añadidos en main entran en el diff como si esta rama los hubiera borrado.
Para probarlo, después de crear la rama hice en main un commit que añade una línea al README, y volví a congelar con --base main. El diff contenía esta línea:
-- `subtotal` ignores nothing: every item counts
Una línea que esta rama no ha tocado se enseña a los revisores como “línea borrada”. Al pasar a --base el punto en que se separó la rama (merge-base), esta línea ya no entró.
dev-orchestra review snapshot --base $(git merge-base main HEAD)
Snapshot: .ai/workflows/pr-check/reviews/review-target.diff
strategy: git diff 77d4296d87f869eb4af4d5cf1ca41b135cef2b31
files: 4
size: 2249 bytes (sha256 27ff110afa0b)
El sha256 coincide con el del primer snapshot, tomado antes de que main avanzara. El diff que enseña un PR de GitHub también es la diferencia desde el punto de separación, así que al enseñar la rama de un PR recomiendo pasar el merge-base. Para comparar con el main remoto, después de git fetch usa el merge-base con origin/main (aquí lo probé con el main local).
7. El contenido de los lockfiles no se envía (review.exclude)
Al actualizar dependencias, el lockfile genera cientos de líneas de diff. No las ha escrito una persona, y aun así consumen tokens por cada revisor. Por defecto, dev-orchestra no envía el contenido de los diffs de lockfiles, dist/, vendor/, node_modules/, JS y CSS minificados, source maps y *.snap (review.exclude).
Para probarlo, en la copia del ejemplo puse un package-lock.json de 306 líneas que hace de lockfile de npm (un archivo nuevo sin commit), añadí también una línea de comentario a cart.py y tomé la instantánea sin --base (el workflow se llama excl).
Snapshot: .ai/workflows/excl/reviews/review-target.diff
strategy: git diff HEAD
files: 1
size: 311 bytes (sha256 a42cd872c7e8)
withheld: 1 file(s), 306 changed line(s) not sent to reviewers
package-lock.json (package-lock.json)
reviewers are told these changed; --no-exclude sends them in full
A los revisores se les comunica el nombre del archivo y cuántas líneas cambiaron, así que no se oculta nada. Si quieres enviarlo todo, añade --no-exclude. Lo de los tokens y el coste lo trato en la 17.ª entrega de la serie (publicación prevista el 23 de noviembre de 2026).
8. También sirve para textos, no solo para código
El diff que se revisa no tiene por qué ser código. En este blog, hago que review run revise los artículos antes de publicarlos (la sección “Revisión” de docs/blog/series.md). Este artículo también lo hice revisar así después de terminarlo, junto con el artículo de la siguiente entrega:
dev-orchestra review snapshot
dev-orchestra review run --only claude-general codex-general --context "These are two Japanese blog posts (a series on dev-orchestra), not code. Review facts, not style: check that every command, option, output and behaviour described matches dev-orchestra 1.3.0, whose docs are in C:/Projects/dev-orchestra (references/reviews.md, references/cli.md, references/workflow.md) and ~/.claude/plugins/cache/dev-orchestra/dev-orchestra/1.3.0. The outputs quoted were captured from real runs against a small sample repo; flag any claim that contradicts the docs, any internal inconsistency between the two posts, and anything misleading to a reader. Repository rules for posts are in CLAUDE.md and docs/blog/writing.md."
A los revisores se les pide que revisen código. Por eso les digo con --context que “son artículos, no código” y dónde comprobar los hechos. Nunca he hecho revisar un artículo sin --context, así que no he probado qué pasa si no se pone (en el comando, sustituí la ruta de mi carpeta personal por ~).
Al hacer revisar juntos este artículo y el de la próxima entrega, claude-general y codex-general dieron 6 hallazgos. Aparte de uno que decía que aún no había traducciones (porque estaba a mitad de escribirlos), encontraron cifras que no cuadraban entre los dos artículos, como “el número de pruebas no coincide entre los dos artículos (deberían ser 3 + 5, no 10)” y “los dos artículos discrepan en cuántos revisores encontraron los fallos”. Los corregí todos.
Las desventajas
- El diff se envía al proveedor de cada revisor registrado. Con la configuración de 4 revisores, se envió tanto a Anthropic como a OpenAI. Los revisores pueden leer en modo de solo lectura los archivos de alrededor, así que puede que no se envíe solo el diff. Para el código que no puede salir de tu organización, usa el método de usar un LLM local como revisor (en inglés)
- En cambios pequeños, por defecto se reduce a un solo revisor. Si quieres enseñárselo a varias IA, tienes que fijar el número con
--onlyuoptimization.level - Los hallazgos son afirmaciones, no hechos. Con 4 revisores salieron 14, pero muchos se solapan; corregirlos tal cual supone pedir la misma corrección varias veces
- Los tokens crecen en proporción al número de revisores. Los revisores se ejecutan en paralelo, así que el tiempo no se alarga mucho, pero el coste se paga por cada revisor
Resumen
- La revisión de dev-orchestra se puede usar por sí sola, sin las etapas de diseño e implementación
- Con
review snapshotse congela el diff, conreview runse revisa y conreview showse lee - El diff congelado y los resultados quedan en
.ai/, y el.gitignorelos deja fuera de los commits - Por defecto, los cambios pequeños se quedan con un solo revisor. Para enseñárselos a varias IA, nómbralas con
--only - Al enseñar la rama de un PR, pasa el merge-base a
--base - Por defecto no se envía el contenido de los lockfiles y similares. También sirve para revisar artículos, no solo código
En la próxima entrega (publicación prevista el 13 de noviembre de 2026) clasificaré los 14 hallazgos de esta vez en aceptados, rechazados y duplicados, y haré que el corrector los arregle.
GitHub: istb16/dev-orchestra (una estrella me animaría mucho)
Todas las entregas de esta serie están en la lista de entregas de «dev-orchestra».
Artículos relacionados
Hice que dev-orchestra revisara una vez más todo el cambio al final
Probé la revisión final de todo el cambio (review.whole_change_recheck) que llegó con dev-orchestra 1.3.0, en un pequeño paquete de Python. Tras una ronda que solo miraba la corrección y no encontró nada, la ronda de todo el cambio encontró un choque entre la corrección y el cambio anterior. Con una corrección que chocaba a propósito, lo detectó antes la ronda de la corrección.
Medí dev-orchestra: el tiempo por petición y los hallazgos según el número de revisores
Con dev-orchestra 1.2.1 pedí añadir una pequeña funcionalidad y medí cuánto tardó (unos 6 minutos sin contar mi aprobación) y cuántos hallazgos se informaron y aceptaron con 1, 2 y 4 revisores. Con más revisores hubo más hallazgos aceptados, pero los que se sumaron eran sobre las pruebas.
Dando a dev-orchestra instrucciones fijas para cada rol
Probé instructions, añadido en dev-orchestra 1.2.1. Las instrucciones fijas para el implementer o los revisores que escribes en el repositorio entran en cada prompt. Compruebo con la salida real cómo se muestran, dónde entran y cómo se trata un cambio en las instrucciones.