Ubicación de la política compartida: docs/DISCOVERY.md, docs/WORKFLOW.md,
docs/LAUNCH-MIGRATION.md, docs/STANDALONE-ENTRY.md, docs/PROCESS.md, docs/using/README.md y docs/using/mirrors.md pertenecen a la raíz del plugin Hatsu resuelta,
no al repositorio consumidor. En una superficie instalada, usa la raíz absoluta impresa por
ten para leer esos archivos (re-resuelve a través de esa habilidad si no está disponible). Los
enlaces relativos a continuación identifican ubicaciones de origen; una copia faltante en docs/ del
consumidor no es una política faltante y no debe activar una presentación duplicada. Nunca copies ni inventes una segunda política en el repositorio de destino.
Ao — la rama, actualizada
Naturaleza: Manipulador. Reconciliar una rama contra su base es una operación del lado de git sobre un cuerpo de trabajo que no es solo tuyo, cualquiera que sea la naturaleza que haya creado el diff.
Pon la base debajo de mí, resuelve solo lo que es texto, y entrégame cualquier cosa que sea significado.
Ao es el primer paso de $murasaki, el tercero de $aka,
y el paso que $en ejecuta cuando un PR se queda atrás. También se puede invocar solo.
Toda su disciplina es una distinción — texto versus significado — y un rechazo: nunca hace push de lo que produce.
0. Entrada independiente — ya total
Ao ya lee el checkout en lugar de un invocador. § 2 lee el estado antes de cualquier cosa, § 3 decide
rebase-vs-merge basado en si algo ha sido publicado, y from <base> lleva la base con
nen/workflow.json → branch.base debajo de ella. docs/STANDALONE-ENTRY.md § 4 la lista como ya total; las cláusulas que
se aplican son P1 — $ten ao cuando ningún compuesto la ejecutó, actualizando los prerrequisitos de esta fase (ten § 6) — y la
base resuelviendo contra la referencia fetched origin/, que § 3 ya requiere.
Nada de una llamada independiente relaja § 6: un conflicto semántico es una parada G5 con ambos lados mostrados, y nunca se resuelve eligiendo el lado que hace que la ejecución continúe. Ao aún nunca hace push, nunca hace force-push, y nunca reescribe un commit que ya está en el remoto.
Devolución. Siguiente en la ejecución cableada: el invocador que necesitaba la rama actual — $murasaki, $aka o $en. No se hizo push, y la evidencia tomada antes de esta actualización está obsoleta si algún rastro rastreado se movió.
1. Invocación
$ao [from <base>]
nen parse ao --grammar "from [<base>]" --line "<la invocación, sin el prefijo $ao>"
Verificado en vivo en v0.3.0 (docs/ab/ao.md § 2.1): from release/1.4 → base: release/1.4; un simple
from se analiza sin la cláusula, salida 0. La cláusula está anclada detrás de un literal por la razón
que $spiritual-message § 1 registra.
Sin cláusula, la base es nen/workflow.json → branch.base, por defecto main cuando la clave o
el archivo están ausentes. Nombra la base en voz alta antes de hacer fetch — una rama actualizada silenciosamente contra
la base incorrecta es un diff que nadie puede leer después.
Un argumento o elemento de configuración faltante se solicita y se configura en línea (missing-argument,
missing-configuration; WORKFLOW.md § 4 Preguntar, configurar, continuar).
2. Leer el checkout primero
nen wc classify --repo <ruta> --base <base> --json
Verificado en vivo en v0.3.0 (docs/ab/ao.md § 2.2), --json lleva exactamente lo que esta habilidad necesita
antes de tocar nada: state.branch, state.isTrunk, state.dirty, state.aheadOfBase,
state.existingCommitSubjects[], state.uncommittedPaths[].
Caso de nen wc classify | Lo que hace ao |
|---|---|
must-move — en la troncal | Rechazar. No hay nada que actualizar: la troncal es la base. Dilo y pasa el invocador a $breath o $tensho, lo que la situación requiera |
on-branch-dirty | Rechazar, nombrando las rutas no confirmadas que el verbo imprimió. Un merge o un rebase sobre trabajo no confirmado o se rechaza en las propias manos de git o entierra el trabajo en un conflicto que nadie puede desenredar. Confírmalo ($kokusen) o guárdalo deliberadamente, luego vuelve a ejecutar |
on-branch-clean | Proceder a § 3 |
nen wc classifyno es un detector de conflictos, y un merge a medio terminar se lee como suciedad ordinaria — verificado en vivo (docs/ab/ao.md§ 2.2). Ejecutado dentro de un merge sin resolver reportaon-branch-dirtycon las rutas en conflicto contadas entre las "ruta(s) no confirmada(s)", sin decir nada sobre el merge en curso. Así que pregunta a git por uno antes de clasificar, nunca a.git/en disco (en un worktree vinculado.gites un archivo):git rev-parse -q --verify MERGE_HEADresolviendo, ogit rebase --show-current-patchsaliendo0(un rebase detenido en un parche: un conflicto, o una paradaedit), significa que una operación anterior se detuvo aquí, y esta ejecución reporta ese estado y no inicia nada — nunca una segunda operación encima de ella, y nunca una re-ejecución dewc catch-updesde aquí, que confirmaría un merge con el mensaje predeterminado de git y sin una compilación re-probada (§ 5). Las otras respuestas de la sonda:1(un rebase pausado sin parche actual, en unbreako unexecfallido) no es asunto de ao, así que la ejecución lo reporta con el propio--continue/--abortde git y se detiene aquí, nunca confiando en catch-up para rechazarlo, lo que un host todavía en nen 0.18.0 o 0.18.1 no hace (zheref/hatsu#182);128es no hay rebase, así que clasificar; cualquier otra cosa se deja a la fila de sonda no respondida de § 3.
3. Qué operación — rebase o merge, decidido por si algo fue publicado
Rebase cuando no se haya publicado nada en esta rama. Merge cuando se haya publicado algo. Reescribir un commit que otra persona ya pudo haber fetchado es la única operación de git que cuesta trabajo a otras personas, y el plano local nunca lo hace.
nen wc catch-up --repo <ruta> --base <base> [--strategy rebase|merge|auto] [--dry-run] [--json]
El verbo primero hace fetch, luego decide, y la decisión se toma contra lo que origin dice ahora,
nunca contra lo que este checkout escuchó la última vez. auto (lo que ao pasa) hace rebase cuando nada de la
rama está en @{upstream} y merge en caso contrario; --strategy rebase|merge nombra una solo donde el
invocador tiene una razón, dicha en voz alta. La salida 0
reporta {base, strategy, before, after, behindBefore, aheadBefore, noOp}, y un noOp: true se
reporta con ambos SHA, nunca como "nada que hacer". Cada otra salida, leída de nen v0.20.0:
| Salida | Qué es | ao |
|---|---|---|
1, con un reporte cuyo conflicted[] no está vacío | un conflicto; la línea de aborto se imprime | § 4 toma el control |
3, un reporte cuyas rutas conflicted[] están todas en el bloque mechanical de nivel superior de nen/contract.json (v0.20.0) | un conflicto que nen clasificó como manifiesto, changelog o espejo; la línea de aborto y los comandos de cada clase se imprimen, ninguno ejecutado | § 4 toma el control, las clases y comandos de nen citados como evidencia; § 4 aún clasifica cada ruta por sí misma |
1, sin reporte | un fetch, estado o lectura de HEAD falló, un rebase o merge falló sin conflicto, o un --continue falló | detenerse: citar la oración de stderr de nen textualmente, decir que el árbol está como git lo dejó; nunca § 4 |
2, un rebase pausado en un break o un exec fallido (v0.18.2) | no es el rebase de ao | citar la oración de nen, que nombra git rebase --continue / --abort; nunca continuarlo o abortarlo |
2, una sonda de rebase que git no respondió (v0.18.2) | puede que no haya ningún rebase | citar la oración de nen y detenerse, sin nombrar ningún comando de git |
2, cualquier otra cosa | un rechazo antes de cualquier mutación: un árbol sucio, un --base que git rechaza, un --strategy que discrepa con la operación en curso, un git demasiado viejo para --end-of-options, sin raíz de repositorio | citarlo textualmente y detenerse |
| cualquier otra salida | inesperada | detenerse y citarla |
strategy: merge→ la rama existe en el remoto → la base se fusionó.strategy: rebase→ nada publicado → la rama se reprodujo enorigin/<base>.
Un rebase sin nada sobre lo que rebasar aún reescribe el SHA, y eso es esperado. Verificado en vivo: una rama ya sentada directamente en la punta de
origin/<base>respondió "Successfully rebased and updated" y movióHEADdec8826c7a84b0444— mismo árbol, mismo mensaje, nuevo objeto de commit, porque el rebase reproduce el commit en lugar de notar que no es necesario. Es inofensivo aquí y solo aquí: § 3 hace rebase solo de una rama no publicada, así que el commit reescrito es uno que nadie ha fetchado. No es inofensivo reportarlo como "nada que hacer" — § 7 pide la base y su SHA resuelto, y una ejecución que dice sin cambios mientrasHEADse movió deja cada referencia posterior al SHA antiguo silenciosamente incorrecta.
Di cuál eligió el verbo y por qué, en una línea, desde su reporte, y nombra la actualización:
"origin fetched; the branch is on @{upstream}, so strategy: merge, not a rebase."
RETIRADO en nen
0.5, reemplazado en0.13. La mitad de merge se ejecutó a través denen pr cascade-main --repo <ruta> --trunk <base> --no-push(verificado en vivo env0.5.0,docs/ab/ao.md§ Retired at nen 0.5) y la mitad de rebase no tenía verbo en ninguna bandera. Ambas mitades son ahoranen wc catch-up's, que nunca hace push.cascade-mainmantiene su filamutatingen la tabla de automatización de izanami, incluyendo--no-push, y ya no es lo que ao llama.
4. Clasificar cada ruta en conflicto antes de resolver una
git -C <ruta> status --porcelain # las filas de conflicto
git -C <ruta> diff --name-only --diff-filter=U # las rutas en conflicto, solas
git -C <ruta> ls-files -u # qué etapas tiene cada ruta
Verificado en vivo contra un fixture construido que lleva uno de cada uno (docs/ab/ao.md § 2.4):
| Porcelain | Tipo | Etapas presentes |
|---|---|---|
UU | both-modified — ambos lados cambiaron el mismo archivo | 1 base, 2 nuestro, 3 suyo |
AA | add-add — ambos lados crearon la misma ruta | 2 nuestro, 3 suyo; sin base |
UD / DU | delete-modify — un lado eliminó lo que el otro editó | solo el lado superviviente |
DD, AU, UA | las formas más raras; clasificar por la misma tabla y nombrarlas | como git reporta |
nen wc catch-up --jsonllevaconflicted[]en la salida1o3, una entrada por ruta no fusionada, conoursytheirstextuales (y, desdenen.wc.catch-up/v0.2, laclassde nen). Lo que no lleva es el tipo, así que la tabla de porcelain anterior aún se lee para eso, y § 6 muestraours/theirsexactamente como el verbo los imprimió. La propia regla del verbo es la que vale la pena citar donde aterriza: nunca elige un lado.
Clasifica cada ruta antes de resolver cualquiera de ellas, e imprime la tabla. Una ejecución que resuelve las primeras tres y descubre que la cuarta es semántica ya ha gastado la confianza del mantenedor en las primeras tres.
5. Mecánico, o semántico
Mecánico — la resolución está determinada, por el repositorio, no elegida por nadie:
- una región de solo adición a la que ambos lados añadieron (un bloque de importaciones, un
.gitignore, una lista de changelog) — mantener ambas, en el orden que la propia convención del archivo da; - un archivo generado o bloqueado que el repositorio regenera (un lockfile, una instantánea, un espejo) — tomar
el lado de la base y regenerar (espejos de Hatsu:
bash scripts/surface_mirror_regenerate.sh), luego probarlo con la compilación declarada (nen shu build; la tabla de salida es$rasengan§ 6's); - una divergencia pura de formato o espacios en blanco sin diferencia de comportamiento;
- un cambio idéntico hecho en ambos lados.
Una colisión de versión de Hatsu puede sobrevivir a una catch-up limpia: ramas paralelas pueden haber elegido el
mismo número. Después de cada catch-up, compara ambos manifiestos reales (.claude-plugin/plugin.json y
.codex-plugin/plugin.json) con la base fresca. Si la versión de la rama es igual o menor que
la de la base, vuelve a aumentar ambos a la misma versión estrictamente por encima de esa base antes de la preparación; actualiza
la línea de versión en el fragmento existente de changelog.d/ de este esfuerzo también. Esto es autoría de Hatsu,
no un re-aumento automático de nen wc catch-up. Después de que se haya decidido la siguiente versión, ejecuta
bash scripts/plugin_version_refs.sh --from <antiguo> --to <nuevo> --body-file <borrador-local> para listar
referencias rastreadas y líneas de borrador. Añade --write para reescribir las formas rastreadas declaradas y cada
token exacto de versión antigua en líneas de borrador no ambiguas; lee las líneas review impresas, que permanecen sin cambios.
El asistente nunca elige la versión, reescribe espejos generados o edita un PR remoto. Regenera los
espejos con el comando anterior, luego actualiza los hechos del cuerpo invalidados por la catch-up:
| Hecho del cuerpo | Re-derivar después de catch-up |
|---|---|
| Versión del plugin | git show HEAD:.claude-plugin/plugin.json y git show HEAD:.codex-plugin/plugin.json después de confirmar el aumento |
| Commits de cabeza y base | git rev-parse HEAD origin/<base> después del commit final y fetch |
| Figuras medidas contra la base (bytes, diff, cobertura, evidencia de revisión) | re-medir contra esa base fresca y cabeza final |
| Número de PR en la línea Drive | gh pr list --repo <propietario/nombre> --state open --head <rama> --json number,url; usa el PR actual devuelto |
| Línea de prerrequisitos del fragmento de changelog | re-medir contra el contrato de dependencia actualizado y los prerrequisitos reales de este esfuerzo |
Revisa el borrador local actualizado, luego usa nen pr edit-body como escritor remoto.
Vuelve a ejecutar la comprobación de aumento contra la base fresca; el punto de rama original no puede probar esta comparación.
Semántico — cualquier cosa donde una persona tenga que preferir una intención a otra. UD/DU es siempre
semántico: "eliminado" y "aún siendo editado" son dos creencias sobre si una cosa existe, y ningún
algoritmo de merge mantiene la creencia. También lo es un UU donde ambos lados cambiaron el mismo comportamiento, y un
AA cuyos dos archivos no son el mismo archivo.
El caso de libro de texto, verificado en vivo (
docs/ab/ao.md§ 2...
[truncado para traducción]