ReferenciaCLI

vx ship

Hacer ship de una mission terminada por el pipeline de tribunal propio de vexillum, abriendo un pull request real

Hacer ship de una mission terminada por el pipeline de tribunal propio de
vexillum, abriendo un pull request real.

Uso:
  vx ship <task-id> [--fix] [--max-rounds <n>] [--timeout <duration>]
                    [--title <text>] [--body <text> | --body-file <path>]

Corre, en orden, dentro del propio camp de la mission: lint, tests, una
revisión adversarial del diff y una verificación de la documentación,
deteniéndose en el primer paso que falla e informándolo, sin pushear ni abrir
nada. Cada paso corre de forma sincrónica; "vx ship" no vuelve hasta que todo
el pipeline terminó, no hay nada externo que seguir después.

La revisión corre en una sesión headless nueva del harness en el que corrió la
mission (Claude Code por defecto) que no tiene nada del contexto del autor: lee
el diff por sí misma con git, asume que el cambio está mal e intenta romperlo, e
informa hallazgos estructurados (archivo, línea,
severidad, acción, un escenario de falla concreto, sitios hermanos) más los
archivos que realmente leyó. Cuando la mission tiene un prompt, cada
componente que introdujo el cambio también se juzga contra él, seguido de las
instrucciones que el general dio después mediante 'vx prompt' y 'vx decide'
(registradas en la tarea como enmiendas), y todo lo que ninguno de ellos pidió
se informa como una advertencia cuyo remedio es quitarlo. Cualquier hallazgo
de severidad error o warning bloquea el ship (incluidos los que necesitan una
decisión humana); los hallazgos info no bloquean y se agregan al cuerpo del
pull request. Un archivo cambiado que el revisor no informó haber leído, una
respuesta que no es un JSON de hallazgos válido después de los reintentos, o
un timeout hacen fallar el paso, nunca pasar. Los hallazgos se imprimen en la
salida de este comando.

Por defecto una revisión que bloquea solo rechaza. Con --fix, los hallazgos
que el revisor marcó auto-fix se entregan a un fixer headless en el camp, su
trabajo se commitea, y lint, tests y la revisión corren de nuevo con un
revisor nuevo que trata los commits del fixer como código sin revisar. Los
hallazgos que necesitan una decisión humana (ask-user) nunca se corrigen: el
ship se rechaza con ellos. El ciclo está acotado por --max-rounds (rondas de
corrección, por defecto 2); agotarlo sin una revisión que pase rechaza el
ship.

  --fix                 habilita el ciclo revisión -> corrección -> revisión
  --max-rounds <n>      máximo de rondas de corrección con --fix (por defecto 2)
  --timeout <duration>  tope absoluto para cada ejecución del revisor o del
                        fixer, por ejemplo 30m (por defecto 20m); excederlo
                        hace fallar el paso

Una vez que todos los pasos pasan, pushea la rama del camp de la mission al
remoto real ("origin") y abre el pull request por sí mismo con "gh pr create",
de forma determinista, sin que ningún soldier ni agente decida si esto ocurre
ni cuándo, ya que es la única acción de vexillum con un efecto real e
irreversible fuera de la máquina. Requiere "gh" ('vx doctor' informa si está
instalado).

El pull request es público, y su texto se produce sin ningún paso manual. La
revisión adversarial, que lee todo el diff y los commits sin contexto del
autor, también propone un título al estilo conventional commit (de unos 72
caracteres) y una descripción corta y factual (qué cambió y por qué, de 3 a 8
líneas), escrita a partir del diff y nunca del prompt de la mission. vx ship
los usa como el título y la sección What. Cuando la revisión los omite o
devuelve unos inválidos, el título es el asunto del único commit de la rama,
o del commit feat, fix o docs más nuevo, o de su primer commit, y What son los
asuntos de los commits como lista de viñetas. El cuerpo también tiene el diff
stat y las áreas de primer nivel tocadas, una línea Verification (los pasos
del tribunal que pasaron, las rondas de revisión y las de corrección), los
hallazgos info de la revisión bajo Tribunal notes, y un pie de una línea que
nombra la mission. Todo lo que viene del camp o del revisor se sanea primero:
se descartan las líneas con una ruta absoluta del home, un puerto de localhost
o algo que parece un secreto, igual que cualquier línea que cite el prompt de
la mission; el texto del revisor que no pasa la verificación no se publica
cortado a medias, lo reemplaza el texto derivado.

Overrides opcionales, solo cuando el texto propuesto no es el que querés:

  --title <text>        usa este título para el pull request
  --body <text>         usa este texto como la sección What
  --body-file <path>    igual, leído desde un archivo ("-" lee la entrada
                        estándar); no se puede combinar con --body

Un cuerpo provisto se sanea como todo lo demás; el diff stat, Verification,
Tribunal notes y el pie se mantienen.

Una mission que ya hizo ship puede volver a hacerlo, para empujar commits de
seguimiento al mismo PR abierto: "done" y "shipped" son los status de partida
válidos, y un re-ship igual corre primero el pipeline de tribunal completo. El
soldier de una mission shipped queda abierto hasta que se hace merge del PR,
así que el trabajo de seguimiento se pide con 'vx prompt <task-id> <text>' (la
tarea pasa a running y después vuelve a done) y se entrega con 'vx ship
<task-id>' de nuevo. Siempre que ya exista un PR para la rama, ya sea que la
tarea esté done o shipped, ship lo reutiliza en lugar de abrir un segundo: pushea
a la misma rama y refresca el título y la descripción del PR a partir de la
nueva revisión (o de --title y --body). Un PR que ya tuvo merge o se cerró no
se reutiliza: ship se rechaza antes de correr nada.

Un soldier que hizo rebase o amend de una rama que ship ya pusheó hace que el
siguiente push no sea fast-forward. Después de cada push exitoso ship registra
en la tarea la punta pusheada. Cuando un push se rechaza por no ser
fast-forward, lee la punta de origin para la rama: si esa punta es exactamente
la registrada, la reescritura es trabajo del propio vexillum y ship reintenta
una vez con un lease fijado a ese commit ('git push
--force-with-lease=<branch>:<sha>', solo la rama de la mission, nunca la rama
base ni ninguna otra ref), imprimiendo una línea que dice que reescribió la
rama del PR y de qué commit a qué commit. Si la punta es cualquier otra cosa
(alguien más pusheó) o no hay un push registrado (una tarea de la que se hizo
ship antes de que esto se registrara), ship nunca fuerza: falla y dice qué
tiene origin y cómo decidir: 'git fetch origin <branch>' e inspeccionarla, o
autorizar un push manual con lease y volver a hacer ship. Una vez que se hizo
ship, aterrizá el PR con 'vx land <task-id>' en lugar de hacer 'vx land' del
camp localmente.