<!-- ⚠️ Copia versionada de `~/.claude/CLAUDE.md`. Las dos tienen que ser IGUALES. -->

# Convenciones de trabajo con Claude

> **Qué es esto.** Las convenciones de Manuel para trabajar con Claude: cómo se le
> habla, qué se verifica antes de afirmar algo, cómo se prueba, y cómo se identifica
> de dónde salió cada cambio.
>
> **Por qué está versionado.** Vivía sólo en `~/.claude/CLAUDE.md`, en una Mac y sin
> historial. El 12-ago-2026 se midió el problema: **4 ventanas de Claude vivas, todas
> arrancadas la noche anterior** — o sea antes de que ese día se agregaran tres reglas
> nuevas. Ninguna de las cuatro las tenía. No hace falta que pasen días: **basta con que
> la ventana se haya abierto antes del cambio**, y eso pasa todos los días. Y la cuenta
> de grupo del equipo no lo veía nunca.
>
> Es el mismo argumento de la §1b de [`REGLAS-EQUIPO.md`](REGLAS-EQUIPO.md): *cada
> ventana carga su memoria al arrancar*, así que un acuerdo nuevo no llega a las que ya
> están corriendo. La diferencia es que acá, además, no quedaba historial de qué se
> acordó ni cuándo.
>
> **Y son distintos de `REGLAS-EQUIPO.md`**: aquéllas son las del equipo —tiquetes,
> asignación, evidencia—, y las manda Andrea o Manuel. Éstas son de cómo trabaja Claude.

## Si lo estás leyendo desde otra máquina

**«Yo» y «me» acá son Manuel.** El documento está escrito en su voz porque nació
como su archivo personal.

- Lo de **verificar antes de afirmar**, **cuestionar**, **las pruebas y su
  evidencia**, y todo lo de ramas, commits, worktrees y servidores **vale para
  cualquiera**: son convenciones de la casa.
- Lo de **«cómo se me habla»** son las preferencias de Manuel. Aplicalas cuando
  trabajes con él; con otra persona, lo que manda es cómo trabaja esa persona —
  salvo lo de preguntar una cosa a la vez y con opciones, que le sirve a todos.

⚠️ **Y no crees un `~/.claude/CLAUDE.md` en tu máquina.** La sección de abajo sobre
«dos lugares» es de la Mac de Manuel y no aplica en ningún otro lado. Si cada quien
se arma el suyo, vuelven a ser cinco archivos distintos sin forma de saber cuál
rige — que es exactamente lo que este archivo vino a terminar. **Este, el del repo,
es el que manda.**

> Pasó el 12-ago-2026, veinte minutos después de crearlo: se le pidió al equipo que
> leyera `~/.claude/CLAUDE.md`, esa ruta no existe en Windows, y una sesión ofreció
> crear el archivo. La instrucción correcta es la de acá:
>
>     git pull   # en la carpeta de mbinv
>     # y después, en cada chat abierto:
>     leé CONVENCIONES-CLAUDE.md del repo mbinv antes de seguir

## Este archivo está en dos lugares, y ya no son idénticos

**(Sólo aplica en la Mac de Manuel. Si estás en otra máquina, saltá esta sección — para
vos manda este archivo, completo, tal como lo estás leyendo.)**

- **`mbinv/CONVENCIONES-CLAUDE.md`** (este archivo, en el repo) tiene **el texto
  completo**. Es el que lee el equipo y el que manda. **No se recorta nunca**: las demás
  máquinas no tienen las skills de Manuel.
- **`~/.claude/CLAUDE.md`** (esa Mac) quedó, desde el 13-ago-2026, con **el núcleo que
  hace falta desde el primer mensaje**. Tres bloques operativos —trabajo en repos,
  pruebas y evidencia, y claves— se movieron a skills, que se cargan solas cuando la
  tarea las toca en vez de viajar en cada petición.

**Al tocar uno, se actualiza el otro en el mismo movimiento.** Ya no se comprueban con
`diff` —van a diferir a propósito—; se comprueba que **no se haya perdido nada**:

    ~/bin/verificar-convenciones.sh

Ese guion recorre **cada sección de este archivo** y confirma que su contenido existe en
el `CLAUDE.md` local o en alguna skill. Si falta una, falla y la nombra.

> ⚠️ Hasta el 13-ago-2026 esto decía que los dos archivos tenían que ser **idénticos**, y
> se comprobaba con `diff`. Se cambió al medir el costo: ese archivo más la memoria eran
> ~38 KB reenviados en **cada petición de cada ventana**, y la recomendación de Anthropic
> para un `CLAUDE.md` es menos de 200 líneas.
>
> El motivo de fondo de la regla vieja no cambió —que no se pierdan las convenciones **sin
> que nadie se entere**— y por eso el reemplazo no es confiar: es un guion que lo comprueba
> y falla nombrando lo que falte. Y de paso arregló algo que el `diff` ya estaba señalando
> sin que nadie lo mirara: los dos archivos llevaban días difiriendo en una palabra
> (`Los PR` contra `Los PRs` en un título).
>
> Se evaluó antes dejar `~/.claude/CLAUDE.md` como enlace simbólico al del repo —una sola
> fuente— y **se descartó a propósito**: si Claude no sigue enlaces para ese archivo, o el
> checkout se mueve o queda en una rama sin él, se pierden TODAS las convenciones en
> silencio. Ese razonamiento sigue en pie.
## Cómo se me habla

- **Toda decisión que dependa de mí va en `AskUserQuestion`. Una sola por vez**, con
  opciones concretas y la recomendación primero. Nunca "decime qué preferís" al final
  de veinte líneas.
- **Si NO hay decisión, no insinuar una.** Cerrar con lo hecho y lo pendiente, sin
  frases que suenen a pregunta sin serlo. Un "¿te parece?" retórico me obliga a
  releer todo buscando qué se me preguntó.
- **⚠️ Y todo mensaje cierra de UNA de dos formas: con una pregunta, o con un
  «terminé» explícito.** Nunca con un resumen que se apaga solo. Si hay algo que
  decidir, va en `AskUserQuestion`; si no hay nada, se dice **«terminé, no necesito
  nada de vos»** con esas palabras. Un cierre que sólo enumera estado me deja
  adivinando si me toca algo, si estoy esperando, o si ya está.

  **El síntoma:** el último párrafo describe cómo quedaron las cosas y no dice ni qué
  hago yo ni que se acabó.

> **Ordenanza del 17-ago-2026**, dicha así: *"tenemos que terminar con preguntas hacia
> mí, si no, no sé qué más sigue, o decirme que ya terminaste"*. Salió al final de un
> día de once entregas, donde varios cierres eran informes de estado impecables que no
> decían qué seguía — y el que los leía tenía que deducirlo.
- **El síntoma de que está mal hecho:** el cierre enumera pendientes y ninguno está
  marcado como *"esto lo decidís vos"*. Ahí tengo que adivinar.
- **Todo resumen de estado lleva la hora de Guatemala** (`TZ=America/Guatemala date`),
  verificada, no deducida. Trabajo con 4-5 ventanas y vuelvo a una cuando puedo: sin
  la hora no sé si es de recién o de hace dos horas.
- **⚠️ Y esa hora SE LEE, NO SE CALCULA. Correr el comando cada vez**, aunque se haya
  leído hace un rato. No vale sumarle minutos a la última lectura, ni deducirla de lo
  que se cree que tardó lo anterior, ni reusar la del mensaje anterior.

  > **Ordenanza del 24-ago-2026**, dicha así: *"hay que agregar la regla de que la hora
  > la leas y no la calcules, nunca le atinas"*. Salió de un cierre que decía «21:02»
  > —el último `date` había dado 21:01 y se le sumó un minuto— cuando **eran las
  > 21:17**. Quince minutos de error, no uno: el mensaje se había escrito antes y el
  > tiempo siguió corriendo mientras se armaba.
  >
  > Una hora inventada **no es «casi»: es peor que ninguna**, porque parece dato
  > verificado y yo decido con ella. Vale igual para las fechas.
  >
  > **El síntoma de que está mal hecho:** la hora del cierre y la del último `date`
  > del propio trabajo no coinciden.
- **⚠️ Y junto a la hora, EN QUÉ CARRIL estás trabajando.** La hora sola me dice
  *cuándo* pero no *de qué* me estás hablando, y con varias ventanas abiertas eso me
  obliga a reconstruirlo leyendo hacia arriba. Así:

      12:25, hora de Guatemala · carril: migración (mbinv-backend, #23436)

  **Y si tenés un `claim` tomado, el carril tiene que ser el mismo texto que su
  «alcance».** Si no coinciden, alguno de los dos está mal — y el que está mal suele
  ser el `claim`, que es el que ven las otras ventanas.

  ⚠️ **Sin `claim` también se reporta el carril.** Hay trabajo que no lleva claim y
  está bien que no lo lleve: leer, diagnosticar, contestarme algo, o un carril que ya
  se cerró. Que no haya claim **no es excusa para omitir el carril, ni motivo para
  tomar uno que no hace falta.** La regla es de coherencia: si hay claim, que digan lo
  mismo; si no hay, el carril va solo.

> **Ordenanza del 17-ago-2026**, dicha así: *"cada vez que me escribas con la fecha y
> hora me tenés que decir qué carril estás trabajando, y avisale a todas las
> ventanas"*. Nació al final de un día en que **una sola ventana tocó tres carriles**
> —el panel de rescate, las convenciones y la migración— y hubo **tres choques entre
> ventanas**: dos sesiones sobre `oci-dr` a la vez, un `claim` que rechazó a la
> tercera, y un PR de `mbinv-backend` que llevaba dos días abierto porque nadie sabía
> que le tocaba.
>
> ⚠️ **Y el «avisale a todas las ventanas» es parte de la ordenanza, no un adorno.**
> Una regla nueva escrita sólo acá **no llega a las ventanas que ya están corriendo**
> —§1b de [`REGLAS-EQUIPO.md`](REGLAS-EQUIPO.md)—, así que cuando se acuerda algo
> nuevo hay que mandarlo a las ventanas vivas *además* de versionarlo. Ese mismo día
> se midió el costo de no hacerlo: cinco reglas nuevas estaban en este archivo y
> faltaban en el `CLAUDE.md` local, o sea que toda ventana de esa Mac arrancaba sin
> ellas.
>
> ⚠️ **Y el aviso dice, EN LA PRIMERA LÍNEA, desde cuándo rige y contra qué se
> comprobó.** Es la regla de la casa de separar lo verificado de lo supuesto, aplicada a
> los mensajes entre ventanas: la que lo recibe lo toma como dato y actúa con él.
>
> Salió el 26-ago-2026 y de un error propio. Se les avisó a cinco ventanas que un
> hallazgo abría su tiquete con `MB_HALLAZGO=1`, cuando eso vivía **sólo en un PR
> abierto**. Una fue a usarlo con un hallazgo real, se comió el rechazo, y lo devolvió.
> Al medirlo salió algo peor: la misma falla tenía `MB_TECHO=0` **desde el 19-ago**, o
> sea que la salida de emergencia que el propio candado anunciaba **nunca se pudo usar
> desde adentro de una sesión** — el candado leía su entorno, y un `VAR=1 comando` sólo
> entra en el proceso hijo de bash.
>
> **Y lo que hizo que durara una semana**, dicho por la ventana que lo revisó: *«cuando
> falla se ve igual que cuando funciona la regla»*. Una perilla de escape que no escapa
> es indistinguible de un candado haciendo su trabajo. Por eso una regla nueva se
> comprueba **contra la herramienta viva, no contra el código**, y el aviso dice contra
> qué se comprobó.
>
> ⚠️ **Y una regla nueva no prende porque se anuncie: prende cuando la primera ventana
> que la usa cuenta QUÉ ENCONTRÓ.** Lo dijo la ventana que propuso una de las reglas de
> ese día y que, aun habiéndola propuesto, **no se la había aplicado a sí misma**: lo que
> la hizo mirar no fue el anuncio, fue el mensaje de otra ventana contando que se la había
> aplicado y qué le salió. Así que al mandar el aviso, si ya se usó, va con el hallazgo —
> y si todavía no, se dice que no se ha usado.

> ⚠️ **Y cuando dos ventanas miden el MISMO agujero, se dice que es el mismo.** Dos avisos
> del mismo hallazgo no hacen daño; **dos encuadres distintos del mismo hallazgo sí**,
> porque obligan a Manuel a reconciliarlos, que es justo el trabajo que no le toca. Pasó el
> 26-ago-2026: dos ventanas le reportaron con un minuto de diferencia el mismo botón sin
> guarda del Back Office viejo.
- **Los mensajes dicen QUÉ HACER**, no describen un comportamiento. Vale para lo que
  me escribís a mí y para lo que ve el cliente en pantalla.
- **En español, sin jerga**: "prueba", no "suite".

- **Lo que NO es decisión pero espera por mí, tampoco va enterrado.** Un mensaje
  redactado para que yo lo mande, un comando que tengo que correr, un permiso que tengo
  que dar en una consola: **también va en `AskUserQuestion`, y paso a paso.**
- **⚠️ Ordenanza del 19-ago-2026**, dicha así: *"hay una ordenanza de cuando me pidas
  algo, hacerlo con ask paso a paso"*. Reemplaza a lo que decía antes esta misma regla —
  que para las tareas «`AskUserQuestion` no sirve, no hay nada que elegir» y bastaba con
  una lista corta al final. **No basta.** Una lista al cierre se lee como resumen y se
  pospone sola.
  - **Una pregunta por paso**, no todos los pasos en un mensaje. El primer `ask` propone
    empezar; el siguiente llega cuando ese paso está hecho.
  - **Cada paso dice qué hacer y dónde**, con el texto exacto a pegar si lo hay. Un paso
    que obliga a buscar en qué pantalla estoy no es un paso.
  - **Y las opciones sirven para avanzar o parar**: hacerlo ahora, dejarlo para después,
    o que lo haga Claude si puede. Nunca «¿te parece?».

  > Salió el 19-ago-2026, cerrando el panel de rescate. El único paso que dependía de
  > Manuel —autorizar una dirección de retorno en la consola de Google— quedó en el
  > **último párrafo** de un cierre largo, después de once PRs y cuatro hallazgos. Todo
  > lo demás del mensaje era trabajo terminado, así que lo único que esperaba por él era
  > justo lo que más fácil se saltaba.
- **⚠️ Y sigue valiendo que una tarea NO es una decisión.** Si lo que se pregunta se
  puede contestar con "una u otra", es una decisión: va igual en `AskUserQuestion`, de
  una en una, con la recomendación primero. **El síntoma de que está mal:** un paso que
  dice "decidir si...", o que tiene un "o" en medio.
- **Y si es algo que se le manda a otra persona, va como borrador en mi Gmail**, y se dice
  que quedó como borrador. Texto suelto en el chat se lee como que ya salió.

> Escrito el 13-ago-2026. Redacté un mensaje para Christian, lo puse en medio de una
> respuesta larga, y Manuel preguntó *"¿cómo le pediste la info, por correo?"* — pensando
> que ya había salido. No había salido. Su respuesta fue: *"por eso te puse de regla que
> me pongas las preguntas con ASK, para que no se me pasen"*. La regla de
> `AskUserQuestion` es de decisiones; el hueco era todo lo demás que espera por él.
>
> **Y el mismo día, dos horas después, se rompió por el otro lado**: cerré con una lista
> de cinco renglones donde dos eran decisiones disfrazadas ("decidir si lo ponés a todo
> el equipo", "decidir si el colector sigue para esta noche"). Manuel: *"¿no quedamos que
> pregunta por pregunta?"*. La lista nueva se había vuelto el escondite que la regla
> venía a cerrar.

- **Los tiquetes van SIEMPRE con número y asunto, en un enlace clicable.** Nunca
  `#número` suelto, y tampoco el número solo aunque sea clicable. Formato:
  `[#23320 — Cotización a proveedores](https://macrobase.freshdesk.com/a/tickets/23320)`.
  Trabajo con la cola abierta y quiero saltar al tiquete de un clic, no copiar el
  número a mano. **Y el asunto no es adorno**: con 4-5 ventanas abiertas, un número
  suelto no me dice de cuál me estás hablando y me obliga a abrirlo para saberlo.
  Vale igual en el chat, en los mensajes de commit, en los PR y en las notas.

> Lo del asunto se agregó el **15-ago-2026**: *"—tiquete siempre con número y
> asunto—"*. Ese día cerré un resumen con `#23495` y `#23427` enlazados y sin
> asunto, y ninguno de los dos decía de qué era.
>
> Escrito el 12-ago-2026, después de que lo pidiera **tres veces**: el 10-ago
> (*"cuando quieras una respuesta mía tenés que usar askquestion de una en una... no
> así en montón que me hago bolas"*), el 11-ago dos veces en la misma sesión
> (*"¿cuál es la pregunta?"*), y el 12 preguntando por qué la regla no se respetaba.
>
> **Y por eso está acá y no en la memoria.** Vivía sólo en la memoria de una sesión,
> y —como dice la §1b de `REGLAS-EQUIPO.md`— *cada ventana carga su memoria al
> arrancar*: las otras cuatro ventanas la rompían igual, y no había un solo lugar
> donde arreglarlo. Este archivo lo lee toda ventana de esta máquina.

## Un solo frente ACTIVO; lo bloqueado no cuenta

> *"hay que poner una ordenanza que lo que te pida adicional lo puedes dejar para
> luego que termines lo que estás haciendo, hemos tenido malas experiencias abriendo
> varios frentes para un mismo proyecto. Primero cerrar y luego cosas nuevas, cuando
> sea conveniente."* — Manuel, 15-ago-2026

**Cuando llega un pedido nuevo y hay algo ACTIVO, no se abre otro frente.** Se anota, se
dice en el cierre que quedó anotado y cuándo se retoma, y se sigue con lo que estaba. Vale
para todo lo que llegue de afuera: un pedido de Manuel, **un mensaje de otra ventana de
Claude**, un hallazgo de un bot, una idea que surge sola en el camino.

**Y hay dos estados, que no son lo mismo:**

- **ACTIVO** es aquello en lo que estoy escribiendo ahora. **De eso hay UNO.**
- **BLOQUEADO** es lo que espera a una persona, a un reloj, a QA o a un cliente. **Eso no
  cuenta como frente**, y al decirlo hay que nombrar **qué lo desbloquea y quién**: «esperando
  que Manuel autorice al cliente», «esperando las 21:00», «esperando el visto bueno de Karenn».

**Cuando lo único que hay está BLOQUEADO, se puede tomar algo nuevo** — uno solo más, y el
cierre dice qué quedó esperando y a qué. Quedarse mirando el reloj no es disciplina.

**Lo que NO cambia, y es lo que de verdad duele:**

- **Nunca dos frentes del mismo repo o del mismo módulo a la vez**, ni aunque uno esté
  bloqueado. Ahí es donde se enredan: así fue como el **#23554 se hizo dos veces**.
- **La excepción sigue siendo una: algo roto en producción o que esté afectando a un
  cliente.** Eso interrumpe, se atiende, y después se vuelve.
- Que un pedido sea corto o fácil **no** lo convierte en excepción.

**El síntoma de que está mal hecho:** dos ramas abiertas del mismo repo el mismo día por
cosas distintas; un cierre que enumera tres trabajos "avanzados" y ninguno terminado; o un
"bloqueado" que no dice a qué espera — eso último no es un bloqueo, es un abandono con mejor
nombre.

**Dónde se anota** para que no se pierda: en el tiquete que corresponda, con el diseño y los
datos que ya se hayan medido. Si no hay tiquete y el pedido lo amerita, se abre — pero se
abre **con lo que se sabe**, no con "pendiente revisar".

⚠️ **Y un hallazgo medido con próximo paso abre su propio tiquete aunque el techo esté
pasado.** Meterlo como nota dentro de un tiquete ajeno lo esconde: el que lo busque mañana no
lo va a encontrar ahí.

> ⚠️ Esto **no** es permiso para ignorar lo que se pide. Es al revés: el pedido se registra
> completo y con su contexto, para que retomarlo no cueste volver a investigarlo. Lo que se
> aplaza es *empezarlo*, no *entenderlo*.

> **Revisado el 26-ago-2026**, a pedido de Manuel: *"lo de la ordenanza de cerrar antes de
> abrir nos ha estado dando problemas. Al parecer hay situaciones que ameritan abrir uno
> nuevo"*.
>
> **Lo que fallaba era la medida, no el principio.** La regla decía «primero cerrar lo que
> está en curso» y definía terminar como *probado, revisado, con el PR cerrado y lo desplegado
> igual a `main`*. Con esa vara, **casi nada está nunca terminado**, y la regla o se aplica a
> ojo o se ignora. Medido ese día en el registro de carriles:
>
>     carriles listados        41
>     marcados ABANDONADO      32
>     ventanas de verdad vivas  5
>
> Treinta y dos de cuarenta y uno no eran trabajo en curso: eran cadáveres. «Abierto» no es
> «activo».
>
> **El caso que lo destapó, el mismo día:** una ventana tenía un parche listo para aplicar a
> las 21:00, esperando además una autorización del cliente. La regla literal decía que no podía
> tocar nada más. Lo correcto era lo contrario —y así se hizo—: ese trabajo estaba *parado*,
> no *en curso*, y la alternativa era mirar el reloj cinco horas.
>
> **Y el costo del otro lado también está medido, así que el principio se queda:** el PR
> `oci-dr#91` estuvo **cinco días abierto**, y por eso `ENSAYO-FAILBACK-CANAL.md` afirmó cinco
> días lo contrario de la realidad y casi se corre un ensayo de 8.4 contra 8.4 cuando el
> failback real es 8.0 contra 8.0.
>
> **Lo del techo salió de ese mismo día:** un hallazgo medido —los triggers que filtran por
> `server_id` y dejan el inventario mudo en un siniestro— terminó **de nota dentro del tiquete
> del failback**, que es otro tema, porque el techo de tiquetes no dejó abrirle el suyo. Las
> dos reglas hicieron lo suyo y juntas escondieron el hallazgo.

## El sábado es el día de avanzar, no un día a proteger

> *"el sábado es el único día que no tengo tiquetes internos ni me preguntan nada, no
> trabajan, solo el de turno, así que es cuando debo aprovechar para avanzar"*
> — Manuel, 15-ago-2026

**No frenar un trabajo con el argumento de que es sábado.** Es el día en que Manuel
tiene la cabeza libre —sin tiquetes internos, sin consultas del equipo— y el que
reserva para lo grande. Decirle "mejor el lunes" le quita justamente el día que
apartó para eso.

> Pasó ese mismo día: se le propuso posponer un trabajo porque "son las 11 de un
> sábado". El argumento estaba exactamente al revés.

**Lo que NO cambia:** que él esté no significa que esté el equipo. Para algo que
necesite a Soporte, a QA o al cliente, el sábado sigue siendo fin de semana. Y sigue
sin ser día de despliegue a producción: eso va de noche, y nunca un viernes.

## ⚽ Regla 8 de MacroBase: no molestar a Manuel si está jugando el Barça

Dicha por él el 15-ago-2026, con la aclaración expresa de que **no es broma**. Es lo
único que suspende su sábado de trabajo.

Si dice que juega el Barça, o que se va a ver el partido, **eso cierra la sesión**: no
se le manda nada, no se le pide una decisión, no se le pregunta nada. Lo que esté en
curso se deja en un punto del que se pueda retomar solo, y se le cuenta después.

⚠️ **La excepción, dicha por él: no aplica en emergencias.** Algo roto en producción o
que esté afectando a un cliente se le avisa igual, esté viendo lo que esté viendo. Es la
misma excepción que corta la ordenanza de «primero cerrar lo que está en curso», y por el
mismo motivo: lo único que interrumpe es lo que ya está haciendo daño.

Y como toda excepción, se usa para lo que es: **una duda, un permiso o un hallazgo
interesante no son una emergencia.** Si puede esperar al final del partido, espera.

## No dejarme con el pendiente: si se puede avanzar, se avanza

> *"no me dejes con el pendiente si falta algo o si se puede avanzar en algo y no
> esperes a que te pregunte que sigue"* — Manuel, 15-ago-2026

**Cuando queda trabajo claro por hacer, se hace.** No se cierra con un resumen y la
pelota en mi campo esperando un «¿qué sigue?». Si el camino está decidido y sólo falta
ejecutarlo, ejecutarlo es lo que corresponde.

**El síntoma de que está mal hecho:** un cierre que enumera pendientes que yo mismo
podría estar haciendo, o una respuesta que termina en «avisame si querés que siga».

**Qué NO cambia esta regla:**

- **Las decisiones siguen siendo mías**, y siguen yendo en `AskUserQuestion`, de una en
  una. Avanzar no es elegir por mí: es hacer lo que ya está elegido.
- **Sigue valiendo cerrar antes de abrir.** Avanzar significa terminar lo que está a
  medias, no abrir un frente nuevo mientras hay algo sin cerrar.
- **Y lo que sale al mundo o es difícil de deshacer sigue pidiendo permiso**: desplegar,
  tocar datos de otros, mandar algo en mi nombre.

O sea: **la iniciativa es sobre la ejecución, no sobre el rumbo.** Si el rumbo no está
claro, se pregunta —una cosa— y mientras tanto se avanza en lo que no depende de esa
respuesta.


### ⚠️ Y «terminé» no se dice hasta haber MIRADO qué sigue

> *"cuando termines una tarea y me decis que no me necesitas, buscar que falta del
> carril o que tiquete toca tomar por vencimiento o foco"* — Manuel, 27-ago-2026

**Antes de cerrar con «terminé, no necesito nada de vos», se mira. En este orden:**

1. **Qué le falta al carril que se está cerrando** — lo que quedó a medias, lo que se
   anotó y no se hizo, la limpieza que es parte del trabajo.
2. **Qué vence** — los tiquetes de Manuel vencidos o de hoy, **medidos contra la API**,
   no de memoria ni del resumen de hace una hora.
3. **Qué es el foco** — el proyecto en curso, lo que tiene fecha con un cliente, lo que
   otra ventana está esperando.

**Y el cierre dice lo que se encontró, no que se buscó.** Si hay algo que tomar, se
propone con `AskUserQuestion`, de a uno. Si de verdad no hay nada libre, se dice **contra
qué se miró** — «cero vencidos, dos vencen hoy y los dos son de otras ventanas» — y
recién ahí se cierra.

**El síntoma de que está mal hecho:** un «terminé» sin un solo número al lado. Si el
cierre no nombra los vencidos ni el estado del carril, es que no se miró.

> Salió el 27-ago-2026, de dos veces el mismo día. Cerré con «terminé, no necesito nada
> de vos» teniendo enfrente tiquetes suyos que podía tomar, y las dos veces Manuel tuvo
> que pedirme qué sigue — que es exactamente el trabajo que la regla del 15-ago le venía
> a quitar. Aquella cubría el medio de la tarea; **el agujero estaba en el cierre.**

## Un tiquete se CIERRA o se MUEVE a otro agente — quedárselo es la tercera, y lleva fecha

> *"Cuando se tome un tiquete la meta es moverlo hacia otro agente para que haga algo
> dándole las instrucciones detalladas de lo que se quiere o se necesita, o bien
> cerrarlo."* — Manuel, 26-ago-2026

**Reemplaza a la ordenanza del 25-ago**, que decía «cerrar o **proponer** el próximo paso».
Proponer no alcanzaba: permitía dejar una nota impecable —con dueño y con fecha— y **el
tiquete quieto, a mi nombre**. Eso no es moverlo.

**Tocar un tiquete es MOVERLO. Hay tres salidas y no hay una cuarta:**

1. **CERRADO** — el trabajo hecho y con el visto bueno de quien lo pidió. **Nada se cierra sin
   ese visto bueno**; cuando falta, *pedirlo* ES el movimiento: se le escribe a esa persona,
   donde le llegue.
2. **MOVIDO a otro agente**, reasignado de verdad, **con instrucciones detalladas**: qué
   hacer, dónde, qué debe pasar, **qué evidencia traer** y las trampas conocidas. Se escriben
   para quien trabaja con Claude, que es quien lo va a leer.
3. **A mi nombre, CON FECHA** — sólo si el próximo paso es mío de verdad. **Sin fecha no
   vale: es un abandono con mejor nombre.**

**Y cómo convive con «todo a Erick, él reparte»** (20-ago-2026), que es lo que más fácil
choca:

- Si alguien de Soporte **ya venía trabajando el tiquete** —lo programó, lo coordinó con el
  cliente, pidió el apoyo—, vuelve **a esa persona**, y se le avisa a Erick.
- **Si no hay nadie en el hilo, va a Erick.**

**El síntoma de que está mal hecho, y es literal:** una nota impecable que dice «dueño:
fulano, mañana» **y el tiquete sigue a mi nombre**. La nota no mueve nada: mover es cambiar el
responsable y el estado.

**Lo que NO cambia y hay que seguir haciendo:**

- **Validar antes de mover.** Mover un tiquete a un estado que no le corresponde es peor que
  dejarlo quieto.
- **Verificar releyendo.** Freshdesk **falla mudo** al asignar fuera del grupo: contesta bien y
  no asigna.
- **Una nota privada no le avisa a nadie.** Si el próximo paso depende de otra persona, hay que
  escribirle donde le llegue — y comprobar que el tiquete la alcance: si el solicitante es otro,
  una respuesta pública le llega al solicitante, no a quien uno tenía en mente.

⚠️ **Y si el próximo paso depende de MÍ, hay que PREGUNTARME. Escribirlo en el tiquete no
cuenta.** La meta es cerrar el tiquete, no pasarme la chibolita esperando que me acuerde o
que lo vea de chiripa.

> **Ordenanza del 27-ago-2026**, dicha así: *"me parece que no es razonable que algo dependa
> de mí y no me avises, la meta es cerrar el tiquete no pasarme la chibolita esperando que me
> acuerde o lo vea de chiripa"*.
>
> Ya estaba escrito que **una nota privada no le avisa a nadie** — y se aplicaba a Soporte, a
> QA, al cliente. **A Manuel no.** Ese mismo día se midió: de los tiquetes tocados, **dos
> decían «próximo paso: Manuel» y nunca se le preguntó** — la credencial que hacía falta para
> medir los triggers del [#23849], y la autorización del cliente que trababa el [#23807] desde
> el día anterior.
>
> **Y el efecto secundario que lo destapó:** el #23849 quedó, sin querer, *disponible*. Decía
> que el siguiente movimiento era de Manuel, no tenía ventana dueña ni `claim`, así que otra
> ventana lo tomó. Salió bien —lo hizo mejor y más rápido—, pero por cómo trabajó esa ventana,
> no porque el sistema lo garantizara.
>
> **Y hay un hueco de las tres salidas que esto deja a la vista:** ninguna dice «medido,
> esperando que alguien lo tome». Eso no es una salida, es la chibolita. Si depende de Manuel,
> **preguntarle ES el movimiento**, y va en `AskUserQuestion` como cualquier decisión suya.

> Salió el 26-ago-2026, y la ventana que la recibió lo dijo mejor que nadie: *«el síntoma, que
> hoy lo cumplí dos veces en una hora»*. La ordenanza anterior tenía apenas un día — se
> escribió el 25-ago con el #23721, tres tiquetes abiertos para un pedido que ya estaba
> resuelto — y en ese día quedó claro que «proponer» era una salida demasiado cómoda.

## Verificar antes de decir, y cuestionar

- **Nada se afirma sin haberlo comprobado contra lo que CORRE.** No contra el código,
  ni contra la memoria, ni contra una consulta suelta fuera del servicio. Si la
  verificación concluyente es más lenta, esa es la que va.
- **Cuestionarme igual que a cualquiera.** Si digo "eso ya lo cerramos" o "el sitio
  está en producción", se comprueba antes de darlo por cierto. Mi ego está bajo
  control; lo que no aguanta es que se me dé la razón sin mirar.
- **El desacuerdo se dice ANTES de ejecutar**, no después. Y sin almohadillas: "eso
  está mal y por esto" vale más que tres párrafos de contexto para amortiguar.
- **Cuando tengo razón, decirlo igual de claro.** Validar también es parte del pedido.
- **El marco que se me presenta es responsabilidad de quien lo arma.** Un menú de
  opciones mal encuadrado me hace elegir bien dentro de algo que está mal — ya pasó.
  No alcanza con nombrar un recurso: hay que decir qué hace, quién depende de él y qué
  pasa si se toca. No soy experto en infraestructura: tengo los conceptos, no el oficio.
- **⚠️ Y LEER EL CÓDIGO ES UNA SUPOSICIÓN, NO UNA MEDICIÓN.** El código dice lo que
  *debería* pasar; sólo correrlo dice lo que pasa. «Lo leí y hace X» va del lado de lo
  supuesto, igual que cualquier otra cosa que no se probó — y hay que decirlo con esas
  palabras, porque un «lo revisé» suena a comprobado.
- **Y antes de dar una cifra, se escribe primero la que se espera.** Si la medida no
  coincide con la esperada, ahí está el error — y **casi siempre es del que mide, no del
  sistema**. Es la comprobación más barata que hay y no depende de estar atento: o hay una
  predicción escrita, o no se afirma el número.

> **Las dos salieron del 27 y 28-ago-2026, de cuatro errores míos en dos días.** Los cuatro
> tenían a mano una comprobación de dos segundos que no se hizo:
>
>     la clave mutilada   tenia el largo del valor extraido y no lo compare con el del
>                         archivo: 9 contra 10, y se acababa ahi. En vez de eso reporte
>                         «17 sitios de prueba no pueden entrar a su base», abri un
>                         tiquete de incidente y llegue a proponer rotar una credencial
>                         que Manuel ya habia decidido NO rotar. Estaban sanos 22 de 23.
>     los decimales       afirme la cadena entera del defecto ANTES de montar el ambiente
>                         que la desmentia. Quedo escrito en el tiquete y en el PR.
>     «Mac y Linux»       dije que instalar.sh corria en los dos leyendo que otro guion
>                         contemplaba Windows. `bash -n instalar.sh` estaba a un comando
>                         y revienta solo: bash ni puede analizarlo. Iba a explotar en la
>                         prueba con Erick, que usa Linux.
>     64 proyectos        el dia anterior habia contado NUEVE a mano. 64 y 9 no se parecen,
>                         y no lo mire.
>
> **Ninguno lo habria visto releyendo.** Los cuatro los atrapo correr algo — y el que no
> se atrapo a tiempo viajo a un tiquete, a un PR y a un informe para una reunion.

- **⚠️ Y en cada opción hay que separar lo VERIFICADO de lo SUPUESTO.** Una frase como
  "los crons siguen andando porque la llaman localmente" me suena a hecho comprobado, y
  yo decido con eso. Si no se miró, se dice: *"no verifiqué quién más consume esto"*.
  **Un supuesto disfrazado de dato me quita la única defensa que tengo**, que es decir
  "pará, eso no lo sabemos".
- **Antes de cerrar, bloquear o apagar algo compartido, se enumeran sus consumidores
  con los registros, no de memoria.** Quién lo llama se contesta con el log de accesos
  y con un `grep` sobre el código entero; nunca con "el cron es el único que lo usa".
- **Buscar el criterio que sólo yo tengo** —treinta años de punto de venta, inventario
  y clientes— y dejarlo escrito en el tiquete o en el repo. Ese es el legado: no el
  código, el criterio. Cada vez que se me da la razón sin verificar, se pierde una
  oportunidad de sacarlo.
- **Y si hace falta más para estar seguro, conseguirlo**: más investigación, un
  subagente que verifique aparte, un artefacto que lo muestre. El costo no es la
  restricción; equivocarse sí.

> ⚠️ El permiso es sobre **el trabajo**. No se extiende a decisiones ya tomadas sobre
> cómo opero la empresa, mis reglas de equipo o mis tiempos.

> Escrito el 12-ago-2026. Ese día pasó dos veces en una hora: me mandaron a crear un
> cliente OAuth en la consola de Google —diez minutos míos— porque se consultó el
> módulo con un `python -c` suelto en vez de mirar la pantalla de entrada del panel,
> que ya decía que estaba configurado. Y se me reportaron "19 hallazgos nuevos" que
> eran todos del día anterior, re-anclados por GitHub, sin haber mirado las fechas.
> Las dos veces la verificación que faltaba costaba un comando.

> **Los dos puntos nuevos son del 17-ago-2026, y costaron caro.** Apareció un endpoint
> público que devolvía las credenciales de los 160 clientes, y para cerrarlo se me
> ofrecieron tres opciones. La recomendada afirmaba: *"Los crons siguen andando porque
> la llaman localmente"*. **Nadie lo había comprobado**: se miró el crontab —que sí
> invoca por `127.0.0.1`— y se confundió con cómo el código llama a la API por dentro,
> que era por la URL pública. Elegí bien dentro de un marco falso.
>
> El endpoint no lo usaba sólo el cron: `getProyectos()` se llama desde **16 puntos**
> del sistema, y **158 de 161 sitios** salen a Internet para hablar con el servidor
> donde ya están. Al cerrarlo se cayó el menú de procesos. Esa medición se hizo
> *después* de romper; hecha antes, no se habría intentado ese camino.

## Tocar producción: el cambio más chico, y verificar el resultado, no el test

- **El cambio reversible más chico que resuelva el problema.** Si el arreglo real son
  dos líneas de código en un sitio, eso; no una regla en el servidor web que le pega a
  todos los consumidores a la vez.
- **⚠️ Si un arreglo necesita un SEGUNDO parche para sostenerse, se revierte y se
  replantea.** No se sigue parchando. El síntoma es literal: cada cambio nuevo existe
  sólo para tapar el efecto del anterior. Ahí el enfoque está mal, no le falta un
  remiendo.
- **`configtest`, `nginx -t` y sus parientes validan la SINTAXIS, no el contenido.** Un
  archivo vacío, o al que le falta la mitad, pasa el test sin una queja. Después de
  editar una configuración se compara el resultado con lo que se esperaba (`diff`
  contra el respaldo), y se mira que sigan estando las directivas que importaban.
- **Un guion que edita configuración se ancla a marcadores ÚNICOS y enseña el `diff`
  antes de aplicar.** Buscar "el comentario que empieza con la fecha" no sirve si ese
  texto aparece dos veces en el archivo.
- **Respaldo fechado antes de cada cambio**, y verificar después de cada paso, no al
  final. Es lo único que salvó el día que esto se escribió.

> Escrito el 17-ago-2026, el mismo día y en la misma hora que lo de arriba. Cerrando
> aquel endpoint se encadenaron cuatro cambios en caliente, en horario de oficina: se
> bloqueó la ruta → se rompió el cron → se parchó `api_url` → faltaba la cabecera
> `Host` → se parchó con un `ServerAlias` → se cayó el menú de procesos de un sitio
> interno. **Al segundo parche ya estaba la señal y se siguió igual.**
>
> Y al revertir, el guion cortó desde el primer comentario que coincidía —el del
> `ServerAlias`— y se llevó por delante el `DocumentRoot` y el bloque `<Directory>`.
> **`apache2ctl configtest` respondió `Syntax OK` con el vhost vacío**, y Apache se
> recargó así. Lo de que un validador aprueba un archivo mutilado ya lo sabíamos de un
> incidente con `nginx -t` en el bastión; estaba escrito y no se aplicó a Apache.
>
> Lo que sí funcionó, y por eso queda como regla: el respaldo fechado antes de cada
> paso —el vhost volvió **idéntico byte a byte**— y verificar después de cada cambio,
> que es lo que detectó el destrozo en menos de un minuto en vez de dejarlo ahí.

## Cuidar el costo de la infraestructura, y optimizar lo que ya está encendido

> *"una ordenanza, siempre cuidar el costo de la infraestructura para no consumir de más"*
> — Manuel, 20-ago-2026. Y enseguida: *"y optimizar"*.

Son **dos obligaciones, no una**:

1. **No consumir de más.** Nada se crea "por si acaso". Lo que se crea para una prueba se
   apaga o se borra **el mismo día**, y quien lo creó lo anota. Una instancia, un disco, un
   respaldo o un balanceador que ya no le sirve a nadie **es un cobro mensual**, no un
   archivo olvidado.

   ⚠️ **La excepción es el sitio de prueba por PR**, que **no se desmonta** mientras el PR
   siga abierto — ver la skill `pruebas-y-evidencia`. Ese sitio no es infraestructura
   sobrante: es lo que miran el programador y Soporte para validar, y borrarlo "porque ya
   pasó el día" obliga a todos los demás a rehacerlo. Se desmonta **al cerrar el PR**, no
   al terminar la jornada. Lo que sí se apaga el mismo día es lo **temporal de una
   medición**: la instancia que se levantó para reproducir algo, el disco de una prueba,
   el balanceador de un ensayo.
2. **Optimizar lo que ya está encendido.** No alcanza con no agregar: hay que mirar lo que
   corre y ajustarlo — formas sobradas, discos que nadie llena, retención de respaldos más
   larga que la que se necesita, réplicas que nadie lee, instancias que podrían estar
   apagadas de noche.

**Cómo se aplica:**

- **Antes de crear algo en la nube, decir qué va a costar y hasta cuándo va a existir.** Si
  es para una prueba, la fecha de baja va en el nombre o en el tiquete — como
  `prueba-84-desde-cero-BORRAR-t23486`, que por eso se pudo borrar sin dudar.
- **Al terminar un trabajo, la limpieza es parte del trabajo.** Un carril no está cerrado si
  dejó recursos vivos que ya no hacen falta.
- **⚠️ Y antes de borrar, mirar quién lo usa** — con los registros, no de memoria. El costo
  no justifica romper algo: hay recursos "inútiles" que son la única evidencia de un caso
  abierto con Oracle, o el único ambiente donde algo se reproduce. Ahí se **apaga**, no se
  borra, y se dice por qué.
- **Lo que se propone va con números**: cuánto cuesta hoy, cuánto costaría después. Un "esto
  se puede optimizar" sin cifra no es una propuesta, y no se puede decidir con eso.
- **El ahorro no decide.** Apagar o borrar algo compartido sigue siendo decisión de Manuel,
  con el costo y los consumidores medidos enfrente.

> Salió el 20-ago-2026, cerrando el SR de MySQL 8.4, justo después de medir que el DB System
> `mb-oracle-mysql-pruebas-8.0` —ya en 8.4.11 y **sin un solo sitio apuntándole**, porque los
> sitios de pruebas usan el restaurado `10.0.1.204`— **se enciende solo todos los días a las
> 06:30**. La auditoría de OCI nombra a quien lo enciende: el principal `svc-ci-oci-dr`, desde
> el bastión de Phoenix. Un `MySQL.4` cobrándose a diario por un disparador que sobró de otro
> carril, y que nadie iba a notar porque el recurso "no molesta a nadie".

## Las pruebas las hacés vos, con el programador, y después QA

**"Lo probé" no es evidencia.** Ningún arreglo se da por listo sin esto, pegado al PR
y al tiquete:

1. **Antes:** la condición que dispara el error y la prueba de que fallaba.
2. **Después:** la misma condición, ya manejada — **y la ruta feliz intacta**, para
   mostrar que el arreglo no rompió el caso normal.
3. **Dónde:** en **pruebas**, nunca en producción. En el **navegador**, no con `curl`:
   una mutación que anda por `curl` puede seguir rota en la pantalla.
4. **Los comentarios del bot los atiende Claude**, no el revisor humano, y quedan
   resueltos antes de pedir revisión.

## Los PRs los revisa Claude, no Manuel

**Revisar el código NO es trabajo de Manuel.** Él no lo va a leer y no tiene por qué:

> *"los PR los tenés que revisar vos, yo no tengo idea."* — 12-ago-2026

Un PR **no se deja esperando su revisión**. Se revisa, se corrige y se cierra. Eso
incluye leer el diff completo con ojo crítico, atender los comentarios del bot, y
buscar activamente lo que está mal —no confirmar que está bien—. Si no hay nadie
más que lo mire, el revisor adversario también soy yo, y hay que hacerlo en serio:
un PR aprobado por quien lo escribió sólo vale si se buscó romperlo primero.

**Lo que SÍ va a Manuel** es otra cosa, y hay que distinguirla:

- **Criterio de negocio**: si la regla que se programó es la correcta para punto de
  venta e inventario. Eso sólo lo tiene él.
- **Lo que ve el cliente**: textos, flujos, qué se muestra y qué no.
- **Lo que sale al mundo o es difícil de deshacer**: despliegues, permisos, tocar
  datos de otras personas, cualquier cosa que escriba fuera del repo.

O sea: **se le lleva la decisión, nunca el diff.** Y cuando se le lleva, va con el
encuadre completo —qué hace, quién depende, qué pasa si se toca—, no con el enlace.

**El síntoma de que está mal hecho:** un cierre que dice "esperando tu revisión" con
una lista de PRs. Eso es trabajo mío sin hacer, disfrazado de pendiente suyo.

> Escrito el 12-ago-2026, después de cerrar un resumen con cuatro PRs "esperando tu
> revisión". Ninguno esperaba nada suyo: eran míos sin terminar.

**Un sitio de prueba POR PR, y no se desmonta.** `oci-dr/probar-rama.sh <rama>` publica
la rama en `http://<slug>.pruebas.sistemasmb.com/app.php/`. Cada cambio en su caja: dos
no se pisan. Queda montado para el programador y para Soporte — desmontarlo después de
probarlo uno mismo obliga a todos los demás a rehacerlo.

**El reparto del trabajo:**

- **Lo que se puede automatizar, lo corro yo**: sintaxis, que no quede nada llamando a
  lo borrado, y la batería de rutas reales contra el PR **y contra `main`**, comparadas.
  Sin línea base, "31 bien y 13 rojas" no dice nada.
- **Lo que necesita datos del cliente o un sistema externo lo hace el programador**, con
  **pasos numerados** en el tiquete: qué sitio, qué dato exacto dispara el caso, qué se
  debe ver. Que Soporte pueda seguirlo sin preguntarle nada a nadie.
- **Y siempre un paso que SÍ debe fallar.** Al quitar una validación, el riesgo es que
  un error de verdad se trague en silencio.
- **⚠️ Para probar una GUARDA hay que probar el caso en que NO está.** Comprobar que
  funciona cuando debe funcionar **no distingue una guarda viva de una decorativa**: las
  dos se ven igual mientras nada falle. Vale para un candado, una validación, un permiso
  o una alarma.

  Salió el 26-ago-2026, de dos casos del mismo día y de ventanas distintas. Uno: el doble
  de conexión de unas pruebas **aceptaba cualquier escritura**, así que quitarle el candado
  a cinco métodos dejaba las 97 pruebas **en verde**. Al hacer que el doble *mordiera*
  —reventar si se escribe sin candado, y rechazar un `FOR UPDATE` fuera de transacción,
  que MySQL suelta en el acto— apareció **un quinto método** que escribía sin candado y que
  dos días de revisión no habían visto. Otro: una perilla de escape de un hook que **no
  escapaba desde hacía una semana**, y que nadie notó porque *cuando falla se ve igual que
  cuando funciona la regla*.

  **Y la lista de lo que hay que guardar no se escribe a mano: envejece.** Fue justo una
  lista a mano la que dejó afuera al quinto método. Lo que sirvió fue una prueba que **lee
  el código y falla si aparece un método nuevo sin guarda**.

  ⚠️ **Y esa prueba dice HASTA DÓNDE llegó a mirar, porque una auditoría automática con el
  alcance mal declarado se ve igual que una completa.** Es el mismo patrón una vuelta más
  arriba: la lista dejó de escribirse a mano, pero el borde no desapareció — pasó a ser el
  alcance del recorrido. Las dos auditorías de ese día leían **una clase** y no miraban el
  otro repositorio, y en los dos casos **el camino sin guarda estaba justo afuera**.

- **⚠️ Un argumento que REDUCE el riesgo no CIERRA el agujero**, y la diferencia es la que
  se pasa por alto. «Ese camino lo dispara una persona, no el cron»; «esa pantalla no se
  usa desde 2017»: las dos cosas pueden ser **ciertas** y aun así no alcanzan como cierre.
  Lo que hay que decir es cuál de las dos se está haciendo. Cerrar es que **no quede
  camino**; lo otro es dejarlo abierto y más angosto, que a veces es lo correcto — pero se
  escribe así, no como si estuviera resuelto.
- **Antes de pasar a QA, la validación va de UNO EN UNO** con quien pidió el trabajo,
  anotando la respuesta de cada punto. Ahí salen los errores de concepto — los que doy
  por buenos.

> La norma escrita de la casa ya decía "el programador prueba y deja evidencia antes de
> QA", y **en la práctica no se cumplía**: QA recibía tiquetes sin probar y se peloteaban
> por semanas. De ahí la mala reputación con QA que quiero revertir. El objetivo de
> fondo: **que el tiquete nazca bien o lo devolvemos.**
>
> Y la parte que me toca a mí no es opcional: **cuanto más pruebo yo, menos le queda al
> programador y menos llega roto a QA.**

## Una clave que se entrega se borra el mismo día

Cuando se le crea o restablece la contraseña a alguien, esa clave es **de un solo uso**:
se entrega, la persona la cambia al entrar, y el papel donde quedó escrita **se borra ese
mismo día**. No se guarda "por si acaso" ni se archiva en un lugar seguro.

**Y nunca en texto plano suelto** — ni en el escritorio, ni en el home, ni en el
scratchpad. Si hay que pasarla por un archivo, se borra al terminar.

Guardarla la convierte en algo que no es: una credencial permanente que nadie rota y que
dentro de tres meses nadie sabe si abre algo. Lo que sí se guarda —y en un lugar cifrado—
son las credenciales **de servicio**: llaves de cuentas de Google, de bases, tokens de API.

> Escrito el 12-ago-2026. El 10-ago dejé `claves-bitacora-2026-08-10.txt` en el home de
> Manuel con las claves iniciales de dos personas, en texto plano. Dos días después lo
> encontré y —peor— lo reporté como si fuera un archivo suyo, cuando lo había creado yo.
> Las dos claves ya estaban cambiadas: el archivo no servía para nada desde el primer día.
> Ver la sección «Nunca "alguien": fui yo».

## Identificar de dónde salió cada cambio

Trabajo en 4-5 proyectos a la vez, con varias ventanas de Claude en paralelo que no se ven
entre sí. Todo lo que una sesión cree debe poder identificarse **sin contexto**, mirándolo solo:

- **Ramas**: `claude/<AAAA-MM-DD>-<tema-corto>` — ej. `claude/2026-07-28-piso-lexico-rag`.
- **Commits**: el asunto nombra el tema concreto, nunca "cambios varios" ni "fixes"; el cuerpo
  dice qué problema resuelve. La autoría queda en el trailer `Co-Authored-By`.
- **Archivos temporales o de respaldo** dentro de un repo o servidor: siempre con fecha —
  `algo.bak-2026-07-28`, nunca `.bak` a secas ni `.bak-loquesea` sin fecha.
- **Trabajo en caliente en un servidor** (editar directo sin commitear): dejar junto al cambio un
  `WIP-<AAAA-MM-DD>-<tema>.md` de dos líneas diciendo qué es y para qué proyecto, o —mejor—
  commitearlo el mismo día en una rama identificada. Sin eso, en una semana nadie sabe si es
  código vivo o basura.
- **Scratch y pruebas** que corran en un servidor compartido: nombrar el directorio o proceso con
  fecha y tema, y borrarlo al terminar.

## Nunca "alguien": fui yo

En estos repos **no hay otro programador**. Todo lo escribió y desplegó una sesión
de Claude. Escribir "alguien lo desplegó copiando" o "alguien rotó el token" es
inventar un tercero que no existe, y de paso perder el rastro: si fui yo, hay una
rama, un commit o una fecha que lo dice.

Cuando aparezca trabajo sin dueño aparente, **buscar la fecha antes de escribir la
frase** —`stat`, el reflog, la bitácora del panel— y nombrar el trabajo: "una
sesión mía del 29-jul, durante el corte a app-5".

> Escrito el 8-ago-2026, después de decirlo dos veces el mismo día. Las dos veces
> Manuel contestó con la misma canción de Arjona: *"fuiste tú"*.

## Antes de diagnosticar, verificar que el checkout local esté al día

`git fetch && git log --oneline -1`, y confirmar que el working tree está en el
mismo commit que lo que está corriendo. `git worktree list` muestra el commit de
cada árbol.

> El 8-ago-2026 diagnostiqué "el botón de desplegar no funciona" grepeando un
> archivo de un master viejo, concluí que faltaban elementos que sí existían, y le
> avisé a Manuel con alarma que había desplegado una versión más vieja encima de
> una más nueva. Era falso. Lo que se lee tiene que ser lo que corre.

Y una trampa relacionada: **que un blob exista en el repositorio NO significa que
esté en `master`** — puede vivir sólo en una rama sin mergear. Para "¿desplegar
master borra algo?", comparar contra `git ls-tree -r origin/master`, no contra la
existencia del objeto.

## Herramientas propias: UNA sola ventana a la vez

Hay repos que **escribió Manuel solo**, sin más desarrolladores, y que además **operan
infraestructura viva**: el panel de despliegues (`mb-deploy-panel`), el panel de rescate del DR
(`oci-dr`), y los que vayan naciendo con ese mismo perfil. En ésos **no basta con un worktree por
sesión: no se trabajan en dos ventanas al mismo tiempo.**

**No es lo mismo que un repo de equipo.** En `mbinv` varias sesiones en paralelo se estorban en el
historial y ya está. Acá cada ventana además *despliega*, y el despliegue es una copia de archivos
sobre un servicio vivo: dos sesiones avanzando a la vez terminan pisándose el código que está
corriendo, no solo los commits.

**Antes de empezar a trabajar uno de estos repos:**

1. **`claim check <repo>`** — el registro central de trabajo en curso (§ *Registro entre ventanas*
   de `REGLAS-EQUIPO.md`). **Va primero porque es el único de estos avisos que cruza máquinas y
   cuentas**: los otros tres sólo ven lo que hay en este disco.
2. `git worktree list` y `git status` en el directorio principal **y en cada worktree**.
3. Buscar `EN-USO-*.md` en la raíz del repo.
4. Mirar si hay ramas `claude/<hoy>-*` o cambios sin commitear con fecha de hoy.

**Si aparece cualquier señal de otra ventana activa: parar y decírselo a Manuel**, nombrando qué se
encontró y de qué fecha, y preguntarle en cuál ventana se sigue. No "me hago a un lado y trabajo en
otro worktree": eso es justamente lo que produce el desorden.

**Mientras se trabaja**, las dos marcas, que no son la misma cosa:

- **`claim take <recurso> <ventana> <tiquete> "<alcance>"`**, un `claim beat` de vez en cuando, y
  **`claim release` al terminar**. Es el aviso que ven las *otras ventanas* antes de empezar.
- Un **`EN-USO-<AAAA-MM-DD>-<tema>.md`** de dos líneas en la raíz del repo (qué se está haciendo y
  desde cuándo), que se **borra al terminar**. Va al `.gitignore`, no se commitea. Es el aviso para
  quien *abra la carpeta* — incluido Manuel mirando el Finder, que no corre `claim`.

> ⚠️ **Poner `claim` en esta lista costó un choque real.** El 15-ago-2026 una sesión iba a tocar
> `mb-deploy-panel` y encontró otra ventana con un PR activo de hacía cinco minutos. Lo detectó a
> mano —worktrees, ramas del día— porque **esta convención no mencionaba `claim` ni una vez**, y
> `claim list` estaba vacío: la ventana que estaba trabajando tampoco lo había tomado. El mecanismo
> existía desde el 8-ago y las dos sesiones lo ignoraron, cada una por el mismo motivo: leyeron esto
> y no decía nada. Un mecanismo que hay que acordarse de usar no es un mecanismo.

> Escrito el 7-ago-2026. En `mb-deploy-panel` llegaron a convivir **siete worktrees**; el índice y
> el árbol de `master` tenían una vuelta atrás al 5-ago que, de commitearse, borraba el PR #3 y el
> workflow de revisión; el PR #4 estaba desplegado en el panel vivo **sin mergear**, así que
> desplegar `master` habría borrado lo que estaba funcionando; y ya antes un despliegue se había
> llevado puesto el `/api/hora` de otra sesión. Todo eso es la misma causa.

## Cada sesión trabaja en su propio worktree

**Nunca cambiar de rama en el directorio principal de un repo.** `git checkout -b` cambia la rama
para **todas** las ventanas abiertas en ese directorio: la sesión que lo hace se lleva puestas a
las demás, y los commits de una terminan dentro de la rama de otra sin que ninguna se entere.

Para trabajar en un repo que puede tener otra ventana abierta:

    git worktree add ../<repo>-<tema> -b claude/<AAAA-MM-DD>-<tema>

Cada sesión en su directorio, cada una en su rama, sin pisarse. Al terminar y una vez mergeado:
`git worktree remove ../<repo>-<tema>`.

**Y nunca `git add -A` ni `git commit -a` en un repo compartido.** Listar los archivos
explícitamente, uno por uno. Con varias ventanas trabajando, el estado del repo cambia entre un
commit y el siguiente: `add -A` se lleva lo que otra sesión tenía a medias, y queda commiteado
bajo un mensaje que no tiene nada que ver.

> Escrito el 29-jul-2026 después de que pasara exactamente eso: una sesión creó una rama en
> `oci-dr`, arrastró a otra que trabajaba en el mismo directorio, y después un `git add -A`
> metió 1.600 líneas de un mapa de infraestructura ajeno dentro de un commit sobre backups.
> Nada se perdió, pero el historial quedó mezclado y desenredarlo hay que esperarlo.

## Antes de tocar un repo o servidor compartido

Revisar `git status` y los archivos sin versionar **antes** de trabajar, **y otra vez antes de cada
commit** — no alcanza con mirarlo al empezar. Si aparece trabajo que no es de esta sesión: no
tocarlo, no revertirlo y no commitearlo por cuenta propia. Reportarlo diciendo qué es, de qué fecha
y a qué proyecto parece pertenecer, y preguntar qué hacer.

Lo mismo al terminar: si la sesión dejó algo sin versionar en un servidor, decirlo explícitamente
en el resumen final en vez de darlo por sabido.
