CommunityRedacción y edicióngithub.com

trailofbits/github-triage

Triagea las issues y pull requests abiertas de un repositorio usando la CLI de gh. Opcionalmente revisa y fusiona PRs listos, cierra issues ya resueltas y asigna estimaciones de prioridad y tamaño localmente.

¿Qué es github-triage?

Esta skill automatiza el proceso de triaje de issues y pull requests en repositorios de GitHub, permitiendo a los usuarios gestionar de manera eficiente el backlog de trabajo pendiente. Utiliza la CLI de `gh` para recopilar información sobre issues abiertos, PRs pendientes y fusionados recientemente, y luego clasifica cada issue en una de tres categorías: ya resuelta (con evidencia como un PR fusionado o commit), con un PR abierto que la resuelve (asegurando referencias cruzadas), o pendiente (asignando prioridad y tamaño localmente). La skill también ofrece manejo opcional de PRs listos, fusionando incrementalmente PRs de bots aprobados y PRs aprobados por mantenedores, y generando subagentes de revisión para PRs nunca revisados. Está diseñada para ejecutarse solo bajo invocación explícita y requiere aprobación del usuario antes de realizar cualquier escritura irreversible en GitHub, como fusiones o cierres de issues. Soporta detección automática del repositorio objetivo basado en los remotos de Git, con opciones para seleccionar manualmente cuando hay múltiples repositorios. La skill prioriza la seguridad al no etiquetar en GitHub las estimaciones locales y al exigir evidencia concreta antes de cerrar issues.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/trailofbits/skills/tree/main/plugins/github-triage/skills/github-triage

Installed? Explore more Redacción y edición skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

GitHub Triage

Triagea las issues y pull requests abiertas de un repositorio. Opcionalmente, primero limpia los PRs listos (fusiona PRs de bots que pasan y PRs aprobados por mantenedores, revisa aquellos nunca revisados), luego cierra issues que ya están resueltas (con un comentario citando el PR o commit que las resolvió), asegura que las issues y los PRs pendientes que las corrigen se referencien mutuamente, y asigna una estimación de prioridad y tamaño solo local a cada issue que aún está pendiente.

Cuándo usarlo

  • Cuando el usuario ejecuta /github-triage para limpiar o revisar las issues abiertas y pull requests de un repositorio.
  • Cuando un backlog de issues se ha desviado: trabajo resuelto que quedó abierto, correcciones que se implementaron sin cerrar sus issues, o PRs en curso que nunca enlazaron su issue.
  • Cuando se han acumulado PRs listos (actualizaciones de dependencias que pasan, PRs aprobados y en verde) o PRs que están sin revisar.

Cuándo NO usarlo

  • No invocar automáticamente. Esta skill realiza escrituras irreversibles en GitHub (fusionar PRs, cerrar issues, publicar comentarios) y solo se ejecuta bajo invocación explícita.
  • No usar para aplicar etiquetas de prioridad/esfuerzo en GitHub. La prioridad y el tamaño se presentan solo localmente y nunca se publican (ver Reglas de Seguridad).
  • No usar como sustituto de la decisión final de fusión de un humano: cada fusión se propone para su aprobación explícita, nunca se realiza de forma autónoma.

Principios fundamentales

  1. Las escrituras están controladas. Calcular el triaje completo primero, presentar cada escritura propuesta (incluidas las fusiones) para revisión, y no ejecutar nada hasta que el usuario lo apruebe.
  2. Evidencia antes de cerrar. Nunca cerrar una issue sin una razón concreta y citada (un PR fusionado o un commit en la rama predeterminada). Cuando la evidencia es débil o ambigua, dejar la issue pendiente y marcarla para revisión.
  3. Prioridad y tamaño se quedan localmente. Son una ayuda interna de planificación para el usuario, nunca se escriben en GitHub.

Flujo de trabajo

Fase 0: Seleccionar el repositorio objetivo

gh auth status                       # confirmar que gh está autenticado
git rev-parse --is-inside-work-tree  # ¿el directorio actual es un repositorio git?
git remote -v                        # enumerar remotos

Determinar el conjunto de repositorios distintos alojados en GitHub entre los remotos. Un remoto está alojado en GitHub cuando la URL del host es github.com, en cualquiera de estas formas:

Normalizar cada uno a OWNER/REPO y eliminar duplicados (una configuración de fork puede tener origin y upstream apuntando a diferentes repositorios de GitHub; múltiples remotos apuntando al mismo OWNER/REPO cuentan como uno).

Regla de selección:

SituaciónAcción
Exactamente un repositorio de GitHub distintoUsarlo como predeterminado — no preguntar.
No es un repositorio git, o cero remotos de GitHubPreguntar al usuario por el OWNER/REPO a triagear.
Más de un repositorio de GitHub distintoUsar AskUserQuestion para que el usuario elija qué OWNER/REPO.

Las instancias de GitHub Enterprise no se pueden detectar automáticamente de manera confiable. Si el usuario trabaja en una instancia de GHE, pedir OWNER/REPO y que configuren GH_HOST / usen el host configurado de gh. Confirmar el repositorio resuelto al usuario antes de continuar.

Almacenar el resultado como REPO="OWNER/REPO" y pasar -R "$REPO" a cada llamada gh. Validarlo con ^[A-Za-z0-9._-]+/[A-Za-z0-9._-]+$ antes de usar, para que una URL remota malformada o hostil nunca fluya a un comando.

Fase 1: Recopilar issues y contexto

# Issues abiertas (gh issue list excluye PRs por defecto)
gh issue list -R "$REPO" --state open --limit 1000 \
  --json number,title,body,labels,assignees,comments,reactionGroups,createdAt,updatedAt,url

# PRs abiertos — candidatos para "corrección pendiente" (fase de issues) y triaje de PRs (Fase 2)
gh pr list -R "$REPO" --state open --limit 1000 \
  --json number,title,body,author,isDraft,reviewDecision,latestReviews,\
mergeable,mergeStateStatus,statusCheckRollup,labels,createdAt,headRefName,url,closingIssuesReferences

# PRs fusionados recientemente — candidatos para "ya resuelto"
gh pr list -R "$REPO" --state merged --limit 300 \
  --json number,title,body,mergedAt,url,closingIssuesReferences

closingIssuesReferences lista las issues que un PR está vinculado a cerrar — poblado por cualquiera de las palabras clave de cierre de GitHub (close/closes/closed, fix/fixes/fixed, resolve/resolves/resolved) en el cuerpo del PR, o por un enlace manual de la interfaz de usuario. Es la señal más fuerte disponible. Para issues que no cubre, también buscar mensajes de commit en la rama predeterminada. Resolver la rama predeterminada de manera autoritativa desde el repositorio seleccionado (no desde origin/HEAD local, que puede no estar establecido o apuntar al remoto incorrecto):

default_branch=$(gh repo view "$REPO" --json defaultBranchRef --jq .defaultBranchRef.name)
# Anclar el número de issue para que #12 no coincida con #120, #123, …
git log --oneline "origin/$default_branch" \
  | grep -iE "(close|fix|resolve)[sd]? +#<N>([^0-9]|$)"

Fase 2: Triagear pull requests abiertos (opcional)

Manejar los PRs antes que las issues: fusionar PRs listos aquí significa que la verificación de "ya resuelto" en la fase de issues verá el trabajo que esas fusiones acaban de implementar.

Si no hay PRs abiertos, saltar esta fase. De lo contrario, resumir los PRs abiertos y preguntar al usuario si desea manejar los PRs ahora (AskUserQuestion: manejar PRs / saltar a issues). Si saltan, ir directamente a la clasificación de issues.

Clasificar cada PR abierto según su estado de revisión, CI y fusión. Las formas de los campos a continuación son lo que gh pr ... --json realmente devuelve — confiar en ellas, no en la intuición:

  • Listo para fusionar = mergeable == "MERGEABLE" y mergeStateStatus == "CLEAN" y CI no está bloqueando (abajo). CLEAN es el veredicto del lado del servidor de GitHub "sin conflictos, no atrasado, no es borrador, checks requeridos en verde" — cualquier otro mergeStateStatus (BEHIND, UNSTABLE, BLOCKED, DIRTY, DRAFT, …) no está listo. Tratar mergeable == "UNKNOWN" (GitHub recalcula la mergeabilidad perezosamente, especialmente justo después de otra fusión) como no listo — volver a consultar brevemente o saltar; nunca fusionar basándose en ello.
  • CI no bloquea — escanear statusCheckRollup (clave en __typename) y rechazar el PR solo ante un problema real: un fallo grave (un CheckRun cuyo conclusion es FAILURE/CANCELLED/TIMED_OUT/ACTION_REQUIRED/STARTUP_FAILURE/STALE, o un StatusContext cuyo state es FAILURE/ERROR), o algo aún en ejecución (un CheckRun status de QUEUED/IN_PROGRESS/WAITING/PENDING, o un StatusContext state de PENDING/EXPECTED — esperar, no fusionar aún). SUCCESS, NEUTRAL y SKIPPED están bien y no deben bloquear (por ejemplo, una ejecución de CodeQL que reporta NEUTRAL en una actualización de dependencia — un PR verde de Dependabot es CLEAN con un check de CodeQL NEUTRAL). Un rollup vacío es sin CI — un estado distinto, nunca tratado como listo. mergeStateStatus == "CLEAN" ya refleja el estado de checks requeridos; usar el rollup para detectar checks no requeridos fallando o pendientes.
  • Bot/automatizado = author.is_bot == true. Cotejar la lista blanca de auto-fusión contra author.login después de normalizar la representación de gh — eliminar un app/ inicial y un [bot] final (gh devuelve Dependabot como app/dependabot en algunas versiones y dependabot[bot] en otras; normalizar ambos a dependabot). En lista blanca por defecto: dependabot, renovate, más cualquier otro que nombre el usuario. Un PR que pasa de un bot no incluido en la lista blanca se reporta, nunca se ofrece para fusionar.
  • Aprobado por mantenedor = latestReviews tiene una entrada con state == "APPROVED" cuyo authorAssociation es OWNER/MEMBER/COLLABORATOR y cuyo author.login no es el autor del PR. No usar reviewDecision == "APPROVED" solo: está impulsado por protección de rama y es null en repositorios sin regla de revisión requerida, por lo que tanto sobreconfía (no puede confirmar acceso de escritura) como pasa por alto aprobaciones genuinas.
  • Nunca revisado = latestReviews no tiene ninguna entrada APPROVED/CHANGES_REQUESTED de nadie que no sea el autor del PR (un comentario de bot de "revisión deshabilitada" de un fork no es una revisión).
CategoríaCondiciónAcción ofrecida
PR de bot fusionablebot en lista blanca + listo + no borradorOfrecer fusión incremental, en orden
Aprobado y listoaprobado por mantenedor + listo + no borradorSolicitar fusión
Nunca revisadono bot + solo el autor ha revisado (o sin revisiones) + no borradorOfrecer generar un subagente de revisión
Necesita trabajoborrador, fallo grave de CI, CI pendiente, conflictos, atrasado, cambios solicitados, o un PR de bot que no está listoSolo reportar — no se ofrece acción

("listo" ya subsume CI-no-bloquea. Los subagentes de revisión son para PRs escritos por humanos — una actualización de dependencia de un bot que no está lista se reporta como Necesita trabajo, no se revisa.)

Presentar los PRs categorizados y ofrecer las acciones aplicables mediante AskUserQuestion.

Fusión incremental, en orden (PRs de bot y PRs aprobados y listos): confirmar el conjunto de fusión y el método de fusión primero (fusionar es irreversible), luego fusionar uno a la vez, los más antiguos primero. Elegir un método que el repositorio permita y fallar cerrado si no lo hace:

gh repo view "$REPO" --json mergeCommitAllowed,squashMergeAllowed,rebaseMergeAllowed   # repositorio posicional, no -R

Para cada PR en orden, verificar de nuevo inmediatamente antes de fusionar (el estado cambia después de cada fusión — un PR fusionado puede dejar al siguiente BEHIND, en conflicto, o recalculando), fusionar de forma síncrona, luego confirmar que se implementó antes de avanzar:

gh pr view <N> -R "$REPO" --json isDraft,reviewDecision,mergeable,mergeStateStatus,statusCheckRollup
# proceder solo si aún está listo: no borrador, mergeable == MERGEABLE, mergeStateStatus == CLEAN, CI no bloquea
gh pr merge <N> -R "$REPO" --<método>     # nunca --auto, nunca --admin
gh pr view <N> -R "$REPO" --json state    # esperar "MERGED" antes de pasar al siguiente PR

Detenerse y reportar si un PR ya no está listo (incluyendo mergeable == "UNKNOWN"), si la fusión no se implementó, o si algún check requerido no está en verde — nunca forzar, --admin, --auto, o saltar un check. Para PRs de bot, mostrar la dependencia y el salto de versión (por ejemplo, saltos mayores) en la compuerta para que el usuario pueda decidir con contexto.

Subagentes de revisión (PRs nunca revisados): cuando el usuario opta, generar un Agente por PR — todos en un solo mensaje de asistente para que se ejecuten en paralelo. Cada subagente revisa el diff de un PR y devuelve una revisión estructurada; escribir cada una en github-pr-<número>-review.md en el directorio de trabajo (sobrescribiendo cualquier archivo anterior para ese PR). Las revisiones son solo lectura y nunca se publican en GitHub. Ver references/reviewing-prs.md para el prompt del subagente, rúbrica de revisión y formato de archivo.

Después de cualquier fusión, volver a obtener la lista de PRs fusionados (la consulta --state merged de la Fase 1) para que la fase de issues pueda detectar issues que esas fusiones resolvieron.

Fase 3: Clasificar cada issue abierta

Ordenar cada issue abierta en exactamente un cubo.

Cubo A — Ya resuelta (el trabajo se implementó, la issue quedó abierta). Requiere evidencia concreta; preferir corroboración sobre una sola señal débil:

  • Un PR fusionado lista la issue en closingIssuesReferences, o su título/cuerpo referencia #N junto con una palabra clave de cierre. (La más fuerte.)
  • Un commit en la rama predeterminada referencia #N con una palabra clave de cierre.
  • El comportamiento que la issue solicita existe demostrablemente en el código actual — verificar leyendo el código relevante con Grep/Read, no asumir. Una implementación diferente o parcial no resuelve la issue.

→ Escritura propuesta: cerrar la issue con un comentario que nombre el PR/commit que la resuelve.

gh issue close <N> -R "$REPO" \
  -c "Resuelta por #<PR> (<razón breve>). Cerrando ya que el cambio ahora está en $default_branch."

Cubo B — PR pendiente la resolvería (un PR abierto aborda la issue). Detectar en cualquier dirección: el closingIssuesReferences del PR abierto incluye la issue; el cuerpo/comentarios de la issue enlazan el PR; o un PR abierto claramente corrige lo mismo que describe la issue. El objetivo es que la issue y el PR se referencien mutuamente — llenar solo lagunas genuinas, y preferir escrituras no destructivas:

  • Sin referencia en ninguna dirección → publicar un comentario de puntero (no destructivo) en el lado que carece de ella. Una mención de #<PR> / #<N> crea una referencia cruzada que GitHub refleja en la línea de tiempo del otro.
    gh issue comment <N> -R "$REPO" -b "Hay una corrección en curso en #<PR>."
    
  • Ya enlazada en al menos una dirección → registrar "ya enlazada — sin acción".

No editar el cuerpo del PR a menos que el usuario quiera explícitamente que el PR cierre automáticamente la issue al fusionarse. Un comentario establece una referencia pero no desencadena cierre automático — solo una palabra clave de cierre en el cuerpo del PR o en un mensaje de commit lo hace. Cuando el usuario opta, nunca sobrescribir la descripción: volver a obtener el cuerpo inmediatamente antes de editar y pasarlo a través de stdin, para que el texto del PR no confiable nunca transite una cadena interpolada por el shell:

body=$(gh pr view <PR> -R "$REPO" --json body --jq .body)
printf '%s\n\nCloses #%s\n' "$body" "<N>" | gh pr edit <PR> -R "$REPO" --body-file -

No duplicar enlaces que ya existen.

Cubo C — Pendiente (sin resolución, sin PR pendiente). Asignar, solo localmente, una prioridad y una estimación de tamaño de cambio (siguiente sección).

Fase 4: Puntuar issues pendientes (SOLO LOCAL)

Prioridad — Critical / High / Medium / Low. Sopesar:

  • Impacto / gravedad — seguridad, pérdida de datos, caídas o errores de corrección tienen prioridad sobre mejoras; docs/cosméticos son los más bajos. Las etiquetas existentes (security, bug, crash, regression) son señales fuertes.
  • Alcance — cuántos usuarios/flujos de trabajo están afectados.
  • Señal — reacciones (👍), informes duplicados, antigüedad con actividad continua.
  • Urgencia — bloquea un lanzamiento, tiene una fecha límite, o tiene una regresión activa.

Tamaño del cambio — el proxy de esfuerzo, expresado como un cubo de camiseta size/* a partir de las líneas totales estimadas (adiciones + eliminaciones, ignorando archivos generados/vendidos), usando la nomenclatura de tamaños de Kubernetes/Prow:

  • size/XS — ≤ 10 líneas
  • size/S — 11‑30 líneas
  • size/M — 31‑100 líneas
  • size/L — 101‑500 líneas
  • size/XL — 501‑1000 líneas
  • size/XXL — >1000 líneas

Si la issue carece de suficiente detalle técnico para estimar, indicar esto en lugar de adivinar.

Fase 5: Reporte de resumen

Después de que el usuario apruebe cualquier escritura propuesta (cierres, fusiones, comentarios, adiciones de palabras clave de cierre):

  1. Ejecutar cada escritura aprobada.
  2. Presentar un resumen tabular: issues cerradas, PRs fusionados, issues enlazadas, issues pendientes (con su prioridad/tamaño asignados y un breve tema de una línea).
  3. Resaltar cualquier issue que quedó abierta pero que podría estar resuelta — aquellas donde la evidencia era débil — pidiendo a un humano que las verifique manualmente.

Reglas de seguridad

  • Todas las escrituras son puestas en escena antes de ejecutarlas. Nunca cerrar, fusionar, o comentar sin aprobación explícita.
  • Las etiquetas de prioridad y tamaño son solo locales. No publicar, ni siquiera como comentarios o referencias, en GitHub — permanecen en el hilo de la sesión.
  • Las revisiones de subagentes son solo locales. Las revisiones se escriben en archivos .md en el directorio de trabajo; nunca se publican en GitHub.
  • Los PRs de bots requieren verificación de lista blanca. Una actualización de dependencia que pasa de un bot no incluido se reporta, nunca se fusiona. Los PRs de bots en lista blanca se fusionan uno a la vez con re-verificación entre cada uno.
  • Sin fusión administrativa. Nunca pasar --admin a gh pr merge, ni usar --auto (que omite checks requeridos). Siempre fusionar de forma síncrona y confirmar.

Referencias

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

trailofbits/address-sanitizer

AddressSanitizer detects memory errors during fuzzing. Use when fuzzing C/C++ code to find buffer overflows and use-after-free bugs.

trailofbits/aflpp

AFL++ is a fork of AFL with better fuzzing performance and advanced features. Use for multi-core fuzzing of C/C++ projects.

trailofbits/agentic-actions-auditor

Audits GitHub Actions workflows for security vulnerabilities in AI agent integrations including Claude Code Action, Gemini CLI, OpenAI Codex, and GitHub AI Inference. Detects attack vectors where attacker-controlled input reaches AI agents running in CI/CD pipelines, including env var intermediary patterns, direct expression injection, dangerous sandbox configurations, and wildcard user allowlists. Use when reviewing workflow files that invoke AI coding agents, auditing CI/CD pipeline security for prompt injection risks, or evaluating agentic action configurations.

trailofbits/algorand-vulnerability-scanner

Scans Algorand smart contracts for 11 common vulnerabilities including rekeying attacks, unchecked transaction fees, missing field validations, and access control issues. Use when auditing Algorand projects (TEAL/PyTeal).

trailofbits/ask-questions-if-underspecified

Clarify requirements before implementing. Use when serious doubts arise.

trailofbits/atheris

Atheris is a coverage-guided Python fuzzer based on libFuzzer. Use for fuzzing pure Python code and Python C extensions.

trailofbits/audit-augmentation

Augments Trailmark code graphs with external audit findings from SARIF static analysis results and weAudit annotation files. Maps findings to graph nodes by file and line overlap, creates severity-based subgraphs, and enables cross-referencing findings with pre-analysis data (blast radius, taint, etc.). Use when projecting SARIF results onto a code graph, overlaying weAudit annotations, cross-referencing Semgrep or CodeQL findings with call graph data, or visualizing audit findings in the context of code structure.

trailofbits/audit-context-building

Enables ultra-granular, line-by-line code analysis to build deep architectural context before vulnerability or bug finding.

trailofbits/audit-prep-assistant

Prepares codebases for security review using Trail of Bits' checklist. Helps set review goals, runs static analysis tools, increases test coverage, removes dead code, ensures accessibility, and generates documentation (flowcharts, user stories, inline comments).

trailofbits/burpsuite-project-parser

Searches and explores Burp Suite project files (.burp) from the command line. Use when searching response headers or bodies with regex patterns, extracting security audit findings, dumping proxy history or site map data, or analyzing HTTP traffic captured in a Burp project.

trailofbits/cairo-vulnerability-scanner

Scans Cairo/StarkNet smart contracts for 6 critical vulnerabilities including felt252 arithmetic overflow, L1-L2 messaging issues, address conversion problems, and signature replay. Use when auditing StarkNet projects.

trailofbits/cargo-fuzz

cargo-fuzz is the de facto fuzzing tool for Rust projects using Cargo. Use for fuzzing Rust code with libFuzzer backend.

trailofbits/chrome-mcp-troubleshooting

Diagnose and fix Claude in Chrome MCP extension connectivity issues. Use when mcp__claude-in-chrome__* tools fail, return "Browser extension is not connected", or behave erratically.

trailofbits/claude-in-chrome-troubleshooting

Diagnose and fix Claude in Chrome MCP extension connectivity issues. Use when mcp__claude-in-chrome__* tools fail, return "Browser extension is not connected", or behave erratically.

trailofbits/code-improver

Runs an autonomous review-and-fix improvement loop over any code target — a skill, plugin, module, or directory — using a reviewer the user names: any installed skill or agent. Keeps a cross-round findings ledger, escalates when fixes stop converging, and guards scope mechanically. Use when asked to 'improve this code until review passes', 'run an improvement loop with <reviewer>', or to iterate review-and-fix with a specific reviewer. For skills prefer the skill-improver entry; for a branch prefer pr-improver.

trailofbits/code-maturity-assessor

Systematic code maturity assessment using Trail of Bits' 9-category framework. Analyzes codebase for arithmetic safety, auditing practices, access controls, complexity, decentralization, documentation, MEV risks, low-level code, and testing. Produces professional scorecard with evidence-based ratings and actionable recommendations.

trailofbits/codeql

Scans a codebase for security vulnerabilities using CodeQL's interprocedural data flow and taint tracking analysis. Triggers on "run codeql", "codeql scan", "codeql analysis", "build codeql database", or "find vulnerabilities with codeql". Supports "run all" (security-and-quality + security-experimental suites) and "important only" (high-precision security findings) scan modes. Also handles creating data extension models and processing CodeQL SARIF output.

trailofbits/constant-time-analysis

Detects timing side-channel vulnerabilities in cryptographic code. Use when implementing or reviewing crypto code, encountering division on secrets, secret-dependent branches, or constant-time programming questions in C, C++, Go, Rust, Swift, Java, Kotlin, C#, PHP, JavaScript, TypeScript, Python, or Ruby.

trailofbits/constant-time-testing

Constant-time testing detects timing side channels in cryptographic code. Use when auditing crypto implementations for timing vulnerabilities.

trailofbits/cosmos-vulnerability-scanner

Scans Cosmos SDK blockchain modules and CosmWasm contracts for consensus-critical vulnerabilities — chain halts, fund loss, state divergence. 25 core + 16 IBC + 10 EVM + 3 CosmWasm patterns. Use when auditing custom x/ modules, reviewing IBC integrations, or assessing pre-launch chain security. Updated for SDK v0.53.x.

Skills relacionados