# Regla: Verificar citas verificables antes de escribirlas o aceptarlas

Esta regla es OBLIGATORIA y aplica a todo contenido que Claude genere o acepte
como válido en cualquier proyecto del usuario donde aparezca una cita
verificable. Cubre dos familias del mismo principio:

1. **Citas normativas / legales / documentales**: artículo de ley o reglamento,
   sección de un estándar, número de RFC/ISO, página de documento oficial,
   referencia a un acuerdo institucional, nombre de un programa o catálogo
   oficial, fecha de promulgación, o atribución de fundamento normativo a una
   entidad de datos.
2. **Citas técnicas archivo:línea**: cualquier afirmación que cite una
   ubicación específica del codebase (`path/al/archivo.py:123`,
   `module/file.ts:45-90`, `schema.sql:438`) en reportes de auditoría,
   análisis de bugs, hallazgos de seguridad, code review, post-mortems,
   reportes de revisión externa, o conclusiones que tú mismo escribas
   acerca del código.

Las dos familias comparten el mismo problema y la misma defensa: el agente
o el reporte afirma evidencia específica, y esa evidencia puede inventarse,
trasladarse mal o estar desactualizada. El antídoto es siempre el mismo:
**`grep` / `Read` sobre la fuente real antes de aceptar o re-emitir la cita**.

---

## Principio

> Antes de escribir una cita verificable (normativa o técnica archivo:línea)
> en código, UI, documentación, reportes, comentarios, docstrings o
> conclusiones, **debes verificarla con `grep` o `Read` sobre la fuente real
> del proyecto**. Si no puedes encontrar evidencia textual de la cita, NO la
> escribas. Una cita plausible que suena correcta NO es una cita verificada.
>
> El mismo principio aplica cuando ACEPTAS una cita ajena: un reporte de
> otro agente, un hallazgo de auditoría, una afirmación del usuario sobre
> "el bug está en X:42". Si vas a actuar sobre la cita (priorizarla,
> remediarla, reproducirla en tu propio output), verifícala primero contra
> la fuente. Aceptar sin verificar es propagar la confabulación.

Las normas mexicanas (RINEMAABMS, LGCG, LAASSP, CONAC, Constitución, leyes
generales) y los estándares técnicos (RFC, ISO, OWASP, WCAG) son tentadores
para confabular contextos plausibles. **Las citas archivo:línea generadas
por otros agentes son tentadoras para aceptar sin verificar** — vienen con
apariencia de evidencia "ya hecha". Plausible ≠ verificado. El costo de
inventar o propagar una cita es pérdida de confianza del usuario y debug
innecesario; el costo de verificar es un `grep` o `Read` de 2 segundos.

---

## Qué cuenta como "cita verificable"

### Familia 1 — citas normativas / legales / documentales

OBLIGATORIO verificar antes de escribir:

- Artículo numerado de una norma: "Art. 23 RINEMAABMS", "Art. 30 LGCG",
  "Art. 134 CPEUM", "fracción IV del Art. 17", etc.
- Número de RFC / ISO / IEEE: "RFC 7231", "ISO/IEC 27001", "IEEE 802.11n".
- Sección de un estándar: "OWASP Top 10 A03", "WCAG 2.1 SC 1.4.3", "NIST
  SP 800-63".
- Nombre de catálogo, programa o acuerdo oficial: "PAAASINE-INE", "PAF",
  "Acuerdo INE/CG2024/15".
- Atribución de fundamento normativo a un dato/tabla/módulo: "según
  Art. X de la norma Y".
- Fechas y números de páginas de documentos oficiales: "actualización
  julio 2017, 71 páginas".
- Citas textuales entre comillas atribuidas a un documento concreto.

### Familia 2 — citas técnicas archivo:línea

OBLIGATORIO verificar antes de escribir o de aceptar como base para acción:

- Ubicación específica de un bug, hallazgo o evidencia:
  `auth/service.py:191-243`, `schema.sql:438-451`, `repository.py:1260`.
- Atribución de un fragmento de código a un archivo: "la función `foo`
  en `bar/baz.ts:42` hace X".
- Cita textual de líneas de código incluidas en un reporte: si el reporte
  pega 4 líneas como evidencia, esas 4 líneas deben coincidir letra por
  letra con el archivo en el HEAD actual del repo.
- Citas dentro de reportes de auditoría externa, nemesis, code review,
  análisis de seguridad, post-mortems, RCAs, hallazgos consolidados
  (incluyendo los que tú mismo emites).
- Conclusiones derivadas de una cita: "es bug porque X:42 ignora Y" —
  hay que confirmar primero que X:42 realmente hace lo que el reporte
  dice.
- Citas en commit messages, PR descriptions o issues que pretenden ser
  evidencia accionable.

NO requiere verificación previa:

- Conceptos genéricos del dominio sin atribución a artículo específico
  ("auditoría interna", "contratación pública", "expediente de
  contratación").
- Conocimiento técnico estable sin cita numérica ("SQL injection",
  "OAuth2 flow", "JWT").
- Descripciones funcionales del propio código que estás editando en
  ese momento.
- Referencias a archivos sin número de línea cuando solo se discute la
  existencia, no el contenido ("el módulo `auth/` está implementado").

---

## Cómo verificar — protocolo obligatorio

### Paso 1: identificar la fuente potencial

Antes de escribir la cita, identifica de dónde podría salir:

- Seeds del proyecto: `grep -rn "TEXTO_CITA" backend/app/seeds/`
- Modelos / docstrings: `grep -rn "TEXTO_CITA" backend/app/modules/`
- Documentación normativa: `grep -rn "TEXTO_CITA" referencia/normativa/`
- ADRs: `grep -rn "TEXTO_CITA" docs/adr/`
- README, CHANGELOG, planning: `grep -rn "TEXTO_CITA" docs/`

### Paso 2: ejecutar la búsqueda

Usar `grep` con el patrón exacto de lo que vas a escribir:

```bash
# Verificar "Art. 23 RINEMAABMS"
grep -rin "art.*23.*rinemaabms\|rinemaabms.*art.*23" path/

# Verificar nombre de catálogo
grep -rin "clasif" referencia/normativa/

# Verificar número RFC
grep -rin "RFC 7231" .
```

### Paso 3: leer la fuente original

Si grep devuelve coincidencias, abrir el archivo con `Read` y verificar
que el contexto sí respalda la cita. Una coincidencia léxica no es prueba
suficiente — el contexto puede ser opuesto al que asumes.

### Paso 4: decidir

- **Si la fuente confirma la cita**: escríbela con el contenido que dice
  textualmente el origen.
- **Si la fuente dice algo parecido pero distinto**: usa el wording real
  del origen, no el que recuerdes de memoria.
- **Si no hay fuente**: NO escribas la cita. Sustituye por descripción
  neutra sin atribución, o pide al usuario la cita exacta.

---

## Protocolo para citas archivo:línea en reportes

Cuando trabajas con un reporte que cita ubicaciones del codebase (auditoría
nemesis, hallazgos de revisor-seguridad-swl, output de revisor-codigo-swl,
informe externo, RCA, post-mortem, hallazgo del usuario):

### Paso 1: clasificar las citas

Lista cada `archivo:línea` mencionada y clasifícala:

- **Crítica accionable** — bug que se va a remediar, hallazgo que se va a
  priorizar, evidencia que se va a citar en un commit o PR. OBLIGATORIO
  verificar.
- **Contextual** — mención de paso en un párrafo sin que ninguna acción
  dependa de su exactitud. Verificación opcional pero recomendada al
  primer hallazgo crítico que la cite indirectamente.

### Paso 2: muestreo mínimo verificable

Si el reporte tiene N citas críticas, verificar como mínimo:

- **Las top 4-6 acciones priorizadas** del reporte (P1 / críticas).
- **Cualquier cita con número exacto de líneas** (`:191-243`, `:438-451`)
  — porque exactitud específica es la más propensa a confabulación.
- **Cualquier hallazgo etiquetado "regresión", "latente" o "extra"** —
  porque suelen detectarse de carambola y son los más frágiles.
- **Cualquier cita que contradiga decisiones documentadas** — un reporte
  que dice "esto está mal" sobre algo que un ADR / APRENDIZAJES dice
  "esto se decidió así" requiere verificación dura antes de actuar.

### Paso 3: verificar con `Read` y `grep`, no asumir

Para cada cita crítica:

```bash
# Verificar que las líneas existen y dicen lo que el reporte dice
Read file_path="<archivo>" offset=<inicio-2> limit=<rango+4>

# Buscar evidencia complementaria (¿hay más sitios con el mismo patrón?)
grep -rn "<patrón>" backend/app/ --include="*.py"
```

Una afirmación del tipo "X:42 ignora la validación" debe verificarse
leyendo X:42 directamente. Si el reporte cita 4 líneas como evidencia,
las 4 líneas deben coincidir con el archivo en el HEAD actual.

### Paso 4: detectar gaps del reporte

Aprovechar la verificación para detectar lo que el reporte NO dice:

- **Sweep por patrón**: si el reporte cita un bug en `X.py:1260` por usar
  `u.col_inexistente`, hacer `grep -rn "u\.col_inexistente"` en TODO el
  módulo para descartar regresiones adicionales. Los reportes suelen
  parar en el primer hallazgo del patrón.
- **Búsqueda inversa**: si el reporte dice "RESUELTO en commit Y",
  verificar que el commit realmente toca el archivo citado.
- **Evidencia complementaria**: si el reporte cita una columna SQL,
  verificar el `CREATE TABLE` del schema correspondiente. La doble
  evidencia (código + schema) refuerza o refuta el hallazgo.

### Paso 5: separar lo verificado de lo no verificado

Al re-emitir conclusiones a partir del reporte:

- **Marca explícitamente qué citas verificaste personalmente** vs. qué
  citas reproducís sin re-verificar.
- **NO presentes el reporte como si fuera tu análisis directo** si no
  lo verificaste. Es propagación de cita ajena, no análisis propio.
- **Si el reporte tiene 11 acciones y solo verificaste 6**, dilo así.
  "Verifiqué 6/11; las 5 restantes asumo correctas por consistencia
  metodológica con las que sí verifiqué" es honesto. "Las 11 acciones
  están confirmadas" cuando solo viste 6 es propagación deshonesta.

---

## Pattern de redacción cuando NO hay cita verificada

En vez de inventar fundamento normativo:

- "Documento oficial INE, actualización julio 2017" (cita textual del seed).
- "Catálogo administrativo interno" (descripción neutra).
- "Definido por el equipo de proyecto" (atribución honesta sin invento).
- Sin cualquier cita ni atribución (preferible a inventar).

NUNCA:

- "Art. X de Y" sin verificación.
- "Catálogo oficial Z" sin verificación.
- "Conforme a la sección N del estándar" sin verificación.

---

## Anti-patrones explícitos

### Confabulación plausible

Inventar una cita que suena correcta porque el contexto sugiere que
podría existir. Ejemplo real (SIGAF, 2026-05-13): asocié "Art. 23
RINEMAABMS" como fundamento del Clasificador de Gasto del INE porque
RINEMAABMS regula contratación INE y el Art. 23 trata adquisiciones —
plausible pero falso. El seed `07_clasificador_gasto.sql` no menciona
ningún artículo, solo cita "Documento oficial INE, actualización julio
2017, 71 páginas".

### Asociación incorrecta entre instrumento y catálogo

Confundir un programa de planeación con un catálogo de clasificación.
Ejemplo: presentar "PAAASINE" (Programa Anual de Adquisiciones del INE,
instrumento de planeación) como si fuera el "catálogo oficial" del
Clasificador de Gasto. Son cosas distintas en el dominio.

### Cita por intuición de memoria del modelo

Atribuir contenido a un artículo o estándar porque "lo aprendí en el
entrenamiento". El conocimiento de entrenamiento sobre normas mexicanas
específicas, especialmente las del INE/OIC y reglamentos administrativos,
es alto en confabulación. Trata cada cita normativa como si NO lo supieras
hasta que el grep al proyecto lo confirme.

### Cita por inferencia transitiva

"Si la norma X regula Y, entonces la cita debe ser Art. N de X". No.
La transición lógica no es prueba documental.

### Cita "para dar peso"

Inventar fundamento normativo para hacer ver la UI/docs como más
profesional o jurídicamente sólida. Una cita falsa es peor que ninguna
cita — destruye la confianza del usuario en TODO lo demás que escribiste.

### Aceptar reporte ajeno sin re-verificar evidencia

Recibir un reporte de auditoría / nemesis / revisor con citas
archivo:línea y proceder a priorizar, planear remediación o re-emitir
las conclusiones SIN haber hecho `Read` ni `grep` sobre las citas
críticas. El reporte puede:

- Tener una cita correcta en archivo pero incorrecta en número de línea
  (el código se movió post-reporte).
- Tener una cita totalmente inventada por confabulación del agente que
  lo produjo.
- Estar desactualizado: el bug citado ya se cerró en un commit posterior.
- Confundir dos archivos similares (`router.py` de módulo A con
  `router.py` de módulo B).

Propagar el reporte como si fuera tu análisis directo es deshonesto y
multiplica el costo del error. La verificación de las top 4-6 citas
críticas toma 5-10 minutos y separa lo verificado de lo asumido.

### Sweep parcial cuando el patrón sugiere más sitios

Verificar la cita exacta del reporte (`X.py:1260`) y detenerse ahí
cuando el bug es **un patrón** (uso de columna inexistente, llamada a
función deprecada, falta de validación). Los reportes de auditoría
suelen parar en el primer hallazgo del patrón. Si verificaste que
`u.col_inexistente` está mal en `X.py:1260`, ejecuta `grep -rn` sobre
toda la base para encontrar los hermanos antes de marcar el hallazgo
como cerrado.

### "El reporte ya lo verificó"

Falacia. Un reporte declara haber verificado, no demuestra haber
verificado. Si vas a actuar sobre la cita, tu firma vale lo que
verificaste personalmente — no lo que el reporte afirma haber hecho.

---

## Excepciones legítimas

NO aplica la regla cuando:

1. **El usuario dictó la cita explícitamente**: si el usuario escribe
   "agrega que esto es por el Art. 23 RINEMAABMS", asume que el usuario
   verificó. Pero si la cita parece dudosa, repregunta.
2. **La cita ya existe en el codebase verificado**: si encuentras "Art.
   23 RINEMAABMS" ya escrito en un docstring del modelo, puedes
   reutilizarlo en UI sin re-verificar la fuente externa (asumes que
   alguien antes la verificó).
3. **Conceptos canónicos sin atribución específica**: "auditoría",
   "expediente", "contratación" — no requieren cita.
4. **Citas de standards técnicos universalmente conocidos sin número**:
   "OWASP", "WCAG" sin sub-versión. Si pones "WCAG 2.1 SC 1.4.3" sí
   aplica la regla.
5. **Cita archivo:línea producida por TU MISMO en ESTE turno** sobre un
   archivo que acabas de leer con `Read` en este mismo turno. La
   evidencia es directa, no necesita re-verificación.
6. **Reporte ajeno que solo vas a leer / archivar / referenciar como
   contexto histórico** sin tomar acción. La verificación se activa
   cuando vas a priorizar, remediar, propagar o concluir a partir del
   reporte.

---

## Familia 2 extendida — reportes COMPACTACION.md y status reports SWL

Los reportes generados por `/swl:compactar` (Delta vN en `.planning/COMPACTACION.md`),
`/swl:checkpoint` (continue-here.md), y similares **son también sub-productos
verificables**. El agente que los escribió puede sintetizar afirmaciones cuantitativas
sin re-verificar contra `git`/`pytest`/`grep`, y el agente que los lee después
hereda los errores si los acepta como base para decisiones.

### Cuándo aplica

OBLIGATORIO verificar antes de tomar acción sobre afirmaciones cuantitativas
extraídas de:

- `COMPACTACION.md` Delta vN (la última sección de cierre de sesión).
- `RESUMEN.md` de fase (conteos de archivos, commits, slices).
- `ESTADO.md` (DT activas, OP pendientes, fases completadas).
- `continue-here.md` (commits pendientes, archivos sin terminar).
- Reportes de auditoría con cifras agregadas ("N hallazgos críticos resueltos").

### Verificaciones rápidas obligatorias

Cuando un reporte declara una cifra accionable, ejecutar la primitiva equivalente
ANTES de basar decisiones en ella:

| Afirmación del reporte | Verificación |
|---|---|
| "N commits sin push" | `git log origin/main..HEAD --oneline \| wc -l` |
| "N archivos modificados" | `git diff --stat HEAD~M..HEAD \| tail -1` |
| "N DT activas" | `grep -cE "^### (DT\|DA\|OP)-" .planning/DEUDAS.md` (sección Activas) |
| "N tests verdes" | output reciente de `pytest --co -q` o último run de CI |
| "Fase N completada" | revisar `NN-CIERRE.md` y commits asociados, no solo el reporte |
| "Cobertura X%" | re-ejecutar `coverage report` si la cifra es relevante para decisión |

### Caso real (origen — sesión SIGM 2026-05-21)

El reporte v10 de COMPACTACION.md afirmó:

> "Trabajo pendiente mapeado: 11 commits acumulados sin push"

Verificación con `git log origin/main..HEAD --oneline | wc -l` retornó **2**.
Los otros 9 commits ya estaban en `origin/main`; el fetch falló por red pero la
referencia local seguía válida. Si el siguiente turno hubiera aceptado el dato
como cierto, habría "esperado créditos GH para pushear 11" sin necesidad.

Lección: el reporte de compactación es un artefacto de prosa con cifras — NO
es la fuente de verdad. La fuente es el filesystem + git + el output de las
herramientas. Tres segundos de `git log origin/main..HEAD` previenen propagación
de error.

### Anti-patrón específico

- **Aceptar el reporte v10 (o vN) tras `/compact` como base de decisiones**: el
  reporte fue escrito por el agente al cerrar contexto, sin re-verificar. Tras
  la compactación, el agente NUEVO lo lee con confianza por defecto y propaga
  cualquier desalineación. Aplicar Familia 2: verificar 2-3 cifras críticas
  del reporte contra git/pytest/grep antes de planificar la siguiente acción.

---

## Familia 2 extendida — comentarios temporales en código

(Absorbe la regla `verificar-citas-temporales.md`, unificada aquí el 2026-06-11
porque su propio texto se declaraba extensión de esta Familia 2.)

> Un comentario en código que afirma alineación con otro commit, versión o
> contrato (`// Alineado con commits X+Y`, `// Refactorizado a vN.M.0`,
> `# Sincronizado con backend`, `<!-- Coherente con schema X -->`) **NO es
> verificación** — es afirmación temporal sin prueba. Antes de actuar sobre el
> comentario como si fuera evidencia, verificar contra la fuente real con
> `grep` / `Read` / `git show`.

El comentario puede haberse desactualizado silenciosamente si el commit
referenciado se revirtió, nunca se aplicó, o el refactor citado cambió después.

**Cuándo aplica**: comentarios que afirman alineación cross-stack o con commits,
versiones, schemas. NO aplica a comentarios de intención, `TODO`/`FIXME` con
ticket, ni explicaciones del POR QUÉ.

**Cómo verificar**: identificar QUÉ se afirma alineado → `git show <SHA> --
<archivo>` o `grep` del campo clave en ambos stacks → comparar campo por campo.
Si hay drift, NO confiar en el comentario: actualizarlo o eliminarlo en el mismo
commit (un comentario stale es peor que ninguno).

**Alternativas seguras** al comentario temporal: test de contrato en CI (en vez
de `// Alineado con commits X+Y`), versión semántica + lock (en vez de
`// Refactorizado a vN`), tipos generados/codegen (en vez de `# Sincronizado con
backend`), validador en pre-commit (en vez de `<!-- Coherente con schema -->`).
Si el comentario es la única opción, incluir **fecha y SHA explícitos** y la
condición de re-verificación.

**Caso de origen** (SIGAF 2026-05-22): `contrato.models.ts:2` decía "Alineados
con el backend refactorizado (commits 284df74 + 5869ac9)" pero el backend nunca
aplicó ese refactor; Pydantic con `extra=ignore` descartaba 5 campos en
silencio y los contratos se crearon sin monto ni vigencia durante semanas. El
comentario funcionó como falso anclaje de confianza para los reviewers.

**Anti-patrones**: confiar en el comentario en code review sin `git show`;
propagarlo en refactors (viaja con el copy-paste hasta volverse falso); no
actualizarlo al revertir el commit citado; usarlo como "prueba" en debates
técnicos.

---

## Origen de esta regla

### Origen Familia 1 — citas normativas (versión inicial)

Sesión 2026-05-13, proyecto SIGAF. Durante implementación del refactor
ADR-076 F4 del form de Nuevo Expediente, agregué como fundamento del
catálogo "Clasificador por objeto y tipo de gasto para el INE" la cita
"Art. 23 RINEMAABMS · catálogo oficial PAAASINE-INE" sin haberla
verificado en ningún archivo del proyecto. Era plausible (RINEMAABMS
regula contratación INE; PAAASINE es el programa anual de adquisiciones)
pero ambas atribuciones eran falsas:

- El modelo `CatClasificadorGasto` y el seed `07_clasificador_gasto.sql`
  no mencionan ningún artículo del RINEMAABMS.
- El seed cita textualmente "Documento oficial INE, actualización julio
  2017, 71 páginas" como fuente — sin asociarlo a artículo legal.
- PAAASINE es un instrumento de planeación, no un catálogo de
  clasificación. Conceptualmente distintos.

El usuario detectó la alucinación al verificar el SQL de referencia y
pidió analizarla. La regla se promueve a global porque el patrón puede
repetirse en cualquier proyecto del usuario que toque normas mexicanas o
estándares técnicos numerados — el sesgo de confabulación plausible no es
específico de SIGAF.

Commit donde se corrigió la alucinación original: `f2b025a` en SIGAF.

### Extensión Familia 2 — citas archivo:línea en reportes

Sesión 2026-05-16, proyecto SIGM. El usuario pidió analizar un reporte
de auditoría nemesis con 16 hallazgos (F-01 a F-16) más 3 hallazgos
heredados (H5.A1, H5.A2, H3.1), todos con citas `archivo:línea`
específicas (`auth/service.py:191-243`, `dependencies.py:73-78`,
`database/init/init.sh`, `catastro/repository.py:1260`, etc.).

Detecté que aceptar el reporte sin verificar habría sido propagación
de cita ajena. Apliqué el principio de la regla original adaptado al
dominio técnico: cada cita crítica priorizada (top 6) se verificó con
`Read` + `grep` contra el código real antes de re-emitir conclusiones.

Resultado: 6/6 hallazgos top verificados al 100%, con **evidencia
adicional** que el reporte no había detallado:

- F-04 lockout: además del backend que no escribe `intentos_fallidos`,
  el schema declara `CHECK (intentos_fallidos >= 0 AND intentos_fallidos
  <= 10)` — el tope de 10 es invariante de la BD, doble confirmación.
- Regresión `u.nombre_completo`: el reporte citó 2 sitios; la
  verificación con `grep -n "u.nombre_completo"` reveló que **podían
  haber más** y el reporte no había hecho sweep global.

Esa última observación se promueve a sub-regla operativa (Paso 4
del protocolo archivo:línea: detectar gaps del reporte con sweep por
patrón).

La adaptación se fusiona en esta regla en lugar de crear una nueva
porque el principio es idéntico — solo cambia el dominio de la cita
(normativa vs. archivo:línea). Mantener una sola regla evita
duplicación operativa y refuerza que el origen del riesgo es siempre el
mismo: una afirmación con apariencia de evidencia que en realidad no
se verificó.

### Extensión Familia 2 — reportes COMPACTACION.md (2026-05-21)

Sesión SIGM 2026-05-21. Tras `/swl:compactar` v10, el reporte declaró
"11 commits acumulados sin push". Verificación con
`git log origin/main..HEAD --oneline | wc -l` retornó **2**. El reporte se
escribió desde la perspectiva del agente al cerrar contexto, sin re-verificar
contra `origin/main` (que sigue local actualizada incluso con `git fetch`
fallando por red).

La adaptación se incorpora como sub-sección "Familia 2 extendida — reportes
COMPACTACION.md y status reports SWL" arriba, no como Familia 3 separada. El
principio es el mismo: afirmación cuantitativa en un reporte = sub-producto
verificable. Cambia el dominio (compactación SWL vs. nemesis auditorías), no
el protocolo.

Lección operativa: las 3 cifras que más se desalinean tras un `/compact` son
"commits sin push" (depende de fetch reciente), "DT activas" (depende del
último Edit de DEUDAS.md vs lo que la prosa del reporte describe) y "tests
verdes" (depende del último run de CI vs lo que el agente recuerda). Verificar
esas 3 antes de decidir siguiente acción.

---

## Checklist antes de escribir una cita verificable (Familia 1)

- [ ] ¿La cita tiene un número, artículo, fracción o referencia
      específica?
- [ ] ¿Ejecuté `grep` o `Read` sobre la fuente real del proyecto?
- [ ] ¿La fuente respalda textualmente la cita?
- [ ] Si no respalda: ¿sustituí por descripción neutra o eliminé la cita?
- [ ] Si no encontré fuente y el usuario no la dictó: ¿pregunté al
      usuario por la cita exacta antes de inventarla?

## Checklist antes de aceptar o re-emitir una cita archivo:línea (Familia 2)

- [ ] ¿Identifiqué cuáles citas del reporte son críticas accionables vs.
      contextuales?
- [ ] ¿Hice `Read` sobre cada cita crítica priorizada (top 4-6)?
- [ ] ¿El archivo:línea citado dice textualmente lo que el reporte afirma?
- [ ] ¿Hice sweep por patrón (`grep -rn`) para detectar hermanos del bug
      que el reporte no listó?
- [ ] ¿Verifiqué evidencia complementaria (schema, ADRs, commits citados)
      antes de aceptar el hallazgo?
- [ ] Al re-emitir conclusiones: ¿marqué explícitamente qué citas
      verifiqué vs. cuáles reproduzco sin verificar?
