Conversaciones de PR
Una pull request ya es el lugar donde ocurre la conversación sobre el código.
Las conversaciones de PR la convierten en una superficie de un espacio de
trabajo de Control Center, igual que un
puente de chat convierte Slack en
una: menciona con @ al bot de la GitHub App del servidor en una PR, responde
dentro de sus hilos de revisión o agrega la etiqueta ai-review, y el trabajo
ocurre en el espacio de revisión de la PR — bajo la misma atribución y las
mismas barandillas que cualquier cosa escrita en la aplicación. Un comentario
también está condicionado a la pertenencia; la etiqueta no, porque no tiene
autor. Las respuestas del bot vuelven a GitHub, en el mismo hilo en el que se
hizo la pregunta.
Tres decisiones dan forma a la función, y cada una es la misma que tomó el puente de chat para el chat, reformulada para un host de código: en qué dirección va la conexión, qué autoriza a un comentario que llega de fuera y a quién se atribuye cada lado.
El sondeo es el transporte
Sección titulada «El sondeo es el transporte»El único canal de envío que GitHub ofrece a una app es un webhook, y un webhook necesita una URL de entrada — justo lo único que esta superficie nunca exige de forma deliberada. Así que el descubrimiento es un barrido: cada minuto o así, una búsqueda con alias por cada instalación de la app le pide a GitHub las PR que mencionan al bot (o su slug corto) y las PR abiertas que llevan la etiqueta de revisión; a las PR que ya tienen un espacio de revisión se les leen sus hilos de comentarios, y todo se compara por id de comentario contra lo visto en el barrido anterior.
Las consecuencias de este diseño merecen nombrarse:
- La latencia es un intervalo de barrido, no un evento. El acuse de recibo 👀 llega en alrededor de un minuto. Nada urgente depende de él.
- Exactamente una vez, por comentario. Los id de comentario son únicos en todo GitHub; cada uno se registra en el momento en que se clasifica como apto, antes de que nada actúe sobre él. Un fallo puede perder el procesamiento de un comentario, pero nunca dispararlo dos veces.
- El tiempo sin conexión se recupera, no se reproduce. El conjunto de lo visto se persiste, así que un reinicio entrega lo que llegó mientras estaba caído. La única excepción es el primer barrido de todos: al no haber memoria contra la cual comparar, todo lo pendiente se registra en silencio — un operador que etiquetó veinte PR antes de que existiera este servidor no debe volver y encontrarse con veinte revisiones en marcha.
- La etiqueta es un conjunto, no un evento. La búsqueda informa la presencia de la etiqueta, así que una PR etiquetada se dispara una sola vez, y nunca más. Volver a agregar una etiqueta después de quitarla es invisible para el barrido; una mención es la vía para volver a ejecutarlo.
La búsqueda se ejecuta una vez por cada cuenta de instalación, con el cliente propio de ese propietario, porque un token de instalación solo ve los repos de su propia instalación — una sola credencial para todo el servidor pasaría por alto en silencio todas las PR de las demás instalaciones de la app.
La pertenencia autoriza, no el comentario
Sección titulada «La pertenencia autoriza, no el comentario»Un comentario de PR llega con poco más que el login de un autor — una identidad externa sin autenticar hasta que se demuestre lo contrario. El bot lo resuelve contra un índice inverso de los miembros del espacio de trabajo y sus cuentas de GitHub conectadas, que se reconstruye según un TTL porque la gente inicia sesión y recibe invitaciones mientras el servidor está en marcha.
Denegar por defecto tiene forma de escalera, y cada peldaño responde en el hilo en el que negó:
- Un login desconocido — no vinculado, o vinculado por alguien que no es miembro de este espacio de trabajo — recibe el aviso de que inicie sesión y se asegure de pertenecer
- Un miembro de solo lectura (
vieweroguest) recibe el aviso de que su rol no puede iniciar trabajo
Los dos casos de login desconocido comparten una misma respuesta: el índice inverso solo devuelve a un miembro de este espacio de trabajo, así que una cuenta no vinculada y una cuenta vinculada que no es miembro son el mismo fallo de búsqueda. Ninguno de ellos continúa. Un comentario nunca se atribuye a alguien que no lo escribió, y las palabras de un desconocido nunca entran en un espacio de trabajo que no pueden ver.
La etiqueta ai-review no tiene autor que resolver, así que no sube por esta
escalera. Agregarla inicia la revisión en el espacio de trabajo que ya tiene
vinculado el repositorio.
Dos identidades, a propósito
Sección titulada «Dos identidades, a propósito»Cada lado de la conversación lleva una identidad distinta, y esa diferencia es la función:
- En GitHub, el bot es el servidor. Cada comentario, reacción y respuesta que publica el puente viaja con el token de instalación de la app. Nadie hizo clic en nada en un cliente, así que nada toma prestada la cuenta de una persona — la misma regla que mantiene los webhooks y el sondeo al margen de las credenciales humanas.
- En el espacio, la pregunta es tuya. El mensaje se atribuye al miembro al que se resolvió el autor, y la ejecución del agente corre en su nombre: los commits lo reconocen como coautor, y el dial de autonomía del espacio y las barandillas de acciones se aplican exactamente igual que a un mensaje escrito en la aplicación. Las escrituras en el host de código que hace la ejecución siguen saliendo como la app — la misma regla que en el punto anterior —, no con el token personal del miembro.
Publicar los hallazgos de la revisión de vuelta en GitHub sigue siendo una decisión de una persona, tomada en Control Center. Una mención puede iniciar una revisión; solo un humano publica una.
La protección contra bucles y el nombre corto
Sección titulada «La protección contra bucles y el nombre corto»Todo lo que firma una cuenta de bot se descarta antes de que se ejecute
cualquier filtro — el nuestro en concreto, y cualquier sufijo [bot], para que
el bot de revisión de otra app tampoco pueda despertar al nuestro. Sin esto,
las propias respuestas del bot llegarían como comentarios nuevos y lo volverían
a disparar indefinidamente.
El sufijo [bot] es también la razón de que exista la forma corta. GitHub fija
el login de la cuenta de una app en <slug>[bot], no ofrece autocompletado
para él y nunca resuelve @slug hacia la app — así que aceptar el slug sin
sufijo es una decisión de nuestro emparejador, y descubrirlo requiere una vía
de búsqueda sobre el texto bruto de los comentarios, no el índice de
menciones de GitHub. El costo se declara en lugar de disimularse: un usuario
humano que comparte el slug de la app menciona al bot cada vez que se menciona a
sí mismo en forma corta. Con nombres de app distintivos, la colisión es
hipotética.
Lo que deliberadamente no se ofrece
Sección titulada «Lo que deliberadamente no se ofrece»- Sin publicación automática. Los hallazgos llegan al espacio de revisión; publicarlos en GitHub es una acción humana aparte
- Sin identidad difusa. El autor se resuelve a exactamente un miembro o se rechaza — no hay atribución por aproximación
- Sin webhook de la GitHub App. Esta superficie nunca registra uno, así que no hay URL de entrada que exponer para los comentarios de PR. Los demás webhooks del producto (pipelines, sincronización de tickets) son una configuración aparte y opcional.
Ver también
Sección titulada «Ver también»- Hablar con Control Center desde una PR de GitHub: la guía práctica para todo esto
- Puentes de chat: las mismas tres decisiones, tomadas para el chat
- Crear la GitHub App: de dónde viene la identidad del bot
- Multijugador — identidad, pertenencia y presencia: los sujetos y los roles por los que se resuelve un login
- Barandillas: lo que puede hacer el agente que responde
- Usar revisión con IA: el pipeline que inicia una mención o una etiqueta