Imported from alejoriosm04/LeagueFlow (
AGENTS.md). Install upstream withnpx skills add alejoriosm04/LeagueFlow. Copyright stays with the author.
Instrucciones para agentes de IA — LeagueFlow
Proyecto académico bajo Spec-Driven Development con GitHub Spec Kit.
Documento completo del flujo: docs/flujo-sdd.md. Principios del proyecto:
.specify/memory/constitution.md (léela antes de generar código).
Reglas no negociables
- La spec manda. No implementes nada que no esté en
specs/NNN-*/spec.md. Si falta información, pregunta o anótalo como Assumption en la spec — no lo inventes en el código. - Nunca hagas
git push --forceni pushes directos amain. La rama está protegida por un ruleset (non_fast_forward,deletion,pull_request). Todo cambio entra por Pull Request desde una ramaNNN-slug. - Nunca escribas secretos en el repo. Ni API keys, ni cadenas de conexión,
ni tokens — tampoco en ejemplos, tests o comentarios. Todo va por variables de
entorno; las llaves nuevas se documentan vacías en
.env.example. GitHub tiene push protection activo y rechazará el push. - El spec se commitea junto con el código que genera, en el mismo PR.
- Decisiones técnicas compartidas: no se re-deciden por HU. El stack, el
modelo de dominio (
League/Team/Player/Match/MatchEvent/User) y el esquema de autenticación y roles están fijados enspecs/001-fundacion-y-autenticacion/plan.mdydata-model.md. Ninguna spec posterior (specs/002-*en adelante) vuelve a correr/speckit-planpara decidir stack o remodelar esas entidades: suplan.mdreferencia el de001y solo documenta lo que añade sobre ese modelo (entidades o campos nuevos propios de esa HU).specs/001-fundacion-y-autenticacionDEBE mezclarse amainantes de que cualquier otra spec empiece su propio/speckit-plan. docs/backlog/backlog.mdes solo referencia histórica. Contiene el backlog completo ya clarificado, de donde se extrajo cada spec individual. No se planifica ni se implementa desde ahí — la fuente de verdad para/speckit-plane/speckit-implementes siemprespecs/NNN-*/spec.md.- Al cerrar una HU, registra sus métricas. Antes de dar por terminada una
HU (tests en verde, antes de abrir el PR), copia
docs/metricas/_plantilla.mdadocs/metricas/NNN-slug.mdy llena la sección "Llenado por el agente" con datos reales de esa HU: tareas completadas, tests escritos y en verde, ciclos de corrección, y qué se reprocesó y por qué. El archivo se commitea en el mismo PR de la HU. Alimentadocs/caso-de-negocio.md, que es un entregable evaluado.- Nunca inventes el costo/tokens de IA ni el tiempo real de trabajo. Esos dos campos los llena la persona; el modelo no tiene acceso a su propio consumo ni al reloj de quien trabaja. Déjalos como están en la plantilla.
- Un
0en "ciclos de corrección" de una HU no trivial es sospechoso: cuenta honestamente, el valor del dato está en que sea real.
Formato de commits y PRs
Conventional Commits, con el número de la HU en el scope:
feat(003): registro de equipos
fix(004): validar cupo máximo del torneo
docs(spec): constitution v1.0.0
chore(ci): pipeline de tests en PR
El título del PR es crítico: el repo usa squash merge únicamente, así que
el título del PR se convierte en el mensaje del commit que queda en main
(y la descripción del PR en el cuerpo). Al abrir un PR:
- Título:
tipo(NNN): descripción en imperativo, en minúscula. - Cuerpo: link a
specs/NNN-*/spec.mdy checklist de criterios de aceptación. - Nunca títulos genéricos tipo "cambios", "update" o "WIP".
Dentro de la rama los commits intermedios pueden ser informales (se colapsan).
Nota sobre GitGuardian en los PR
El repositorio tiene GitGuardian activo y marcará como secreto cualquier par
{"username": ..., "password": ...} en tus tests de autenticación, aunque los
valores se generen en tiempo de ejecución: el detector reacciona al patrón de
claves, no al valor. No es bloqueante — el BLOCKED del PR viene de la regla
que exige una aprobación, no de este check.
Qué hacer:
- Comprueba primero si es real. En
specs/001lo fue: había contraseñas de PostgreSQL enci.ymly en la documentación. Se eliminaron de raíz usandoPOSTGRES_HOST_AUTH_METHOD=trust, sin contraseña que escribir. - Si son fixtures de test, genera los valores (
secrets.token_urlsafe,crypto.randomUUID) y descarta la detección como falso positivo en el panel de GitGuardian. No persigas el patrón cambiando valores: no se limpia así. - Nunca dejes una credencial real en el repo para que "pase el check".
Nota sobre migraciones Alembic e índices funcionales
Los índices únicos de leagues (ix_leagues_unique_name_season) y teams
(ix_teams_unique_league_name) son funcionales: usan lower(trim(...)).
PostgreSQL normaliza trim(x) como TRIM(BOTH FROM x) en su catálogo, así que
al correr alembic revision --autogenerate en las specs 004-* en adelante,
Alembic verá lower(trim(name)) (lo que declara el modelo) como distinto de
lower(TRIM(BOTH FROM name)) (lo que hay en la BD) y generará un
DROP INDEX/CREATE INDEX espurio sobre índices que no cambiaron.
Qué hacer:
- Genera la migración con
alembic revision --autogenerate. - Revisa el diff y borra cualquier
op.drop_index/op.create_indexque recreeix_leagues_unique_name_seasonoix_teams_unique_league_namesin que su definición haya cambiado de verdad. - Deja en la migración solo tu tabla/índice nuevo. Nunca toques índices existentes de specs anteriores (Principio IV: no romper lo que ya funciona).
Nota sobre migraciones en paralelo (bloque de trabajo paralelo)
Las specs 013 a 017 se desarrollan en paralelo por integrantes distintos
(Demo Day). Cuatro de ellas crean migraciones —013 (grupos), 014
(tarjetas/sanciones), 016 (auditoría) y 017 (bloqueo de login)—; la 015
(exportación a CSV) no persiste nada.
Si dos personas corren alembic revision --autogenerate en paralelo contra el
mismo main, Alembic genera dos migraciones con el mismo down_revision y deja
dos cabezas en el historial. Eso rompe alembic upgrade head y el pipeline.
Qué hacer:
- Orden de merge pactado. Las specs que migran se mezclan en orden fijo:
013 → 014 → 016 → 017. La015puede mezclarse en cualquier momento. - Una migración = un archivo, generada contra
mainactualizado y revisada según la nota de índices funcionales de arriba. - Al mergear, re-puntea
down_revision. Antes de abrir tu PR, rebasea tu rama sobremainy deja que tu único archivo de migración apunte (down_revision) a la cabeza ya mezclada. No usesalembic merge headssalvo que sea estrictamente necesario. - No mezcles dos specs que migran "a ciegas" en la misma sesión sin correr
alembic upgrade headdesde base vacía al final (el CI ya lo hace en cada PR).