name: cite-check description: Verifica cada cita y cita textual en un borrador de artículo contra las fuentes reales (casos a través de CourtListener + reporteros oficiales, trabajos académicos a través de la biblioteca Zotero del usuario y luego la web abierta) y devuelve un informe calificado, nota a nota, con una sección de «requiere su atención» primero, más una sección de formato de citas (citas cortas según Bluebook R. 10.9/4.2 y cursivas/versalitas según R. 2.1(a)) decidida solo a partir del borrador. Se activa cuando el usuario desea verificar las citas de un borrador ("cite-check this", "check the citations/quotes in this draft", "run cite-check on "). Entrada: un .docx con notas al pie reales de Word (alternativa en markdown/texto plano). No es un linter completo de Bluebook: el orden de señales, el orden de citas y la composición de las citas quedan fuera.
Verificación de Citas
Un pase de verificación sobre un borrador de artículo terminado o en proceso. Cada autoridad se verifica para comprobar su existencia; cada cita textual se verifica palabra por palabra contra la fuente real; cada URL se confirma que resuelve; las citas a páginas (pincites) se verifican de manera sensata cuando la paginación de la fuente se puede recuperar. Scripts deterministas realizan la extracción y la resolución de referencias cruzadas con un costo de tokens casi nulo; los agentes modelo realizan la verificación de citas textuales y pincites en un abanico de fuente única, con una segunda verificación obligatoria en cada hallazgo de alta gravedad para que un artefacto de verificador nunca llegue al informe.
Reutiliza la maquinaria de la habilidad legal-research (check_cite.py, fetch_page.py, el token de CourtListener, la escalera de degradación presupuestaria) y sus reglas internas (solo web abierta, nunca verificar desde la memoria, una fuente no recuperable se informa como no verificada, nunca se asume).
Lo que verifica: que cada cita resuelva a la fuente reclamada, que los epígrafes/autores/títulos estén escritos correctamente, que el reportero/volumen/primera página/corte/año sean correctos, que las citas textuales sean literales o estén marcadas honestamente, que las referencias cruzadas supra/id. estén intactas, y que las URLs estén activas.
Registro de cobertura (añadido 2026-09-06) — y lo que AÚN NO se verifica. Las unidades de verificación de citas textuales se construyen a partir de citas textuales; por sí solas dejaban sin contabilizar cada fuente secundaria no citada textualmente. Ahora scripts/citation_ledger.py inventa cada instancia de cita en cada nota al pie (caso o secundaria, citada textualmente o no, con cadenas de Id./supra/forma corta resueltas), un pase de existencia de fuente secundaria cubre los artículos/libros/estatutos/URLs no citados textualmente, y la sección H del informe asigna a cada instancia una disposición — verified, finding, existence-only, unverifiable, unchecked, xref, unresolved-xref — y enumera las no verificadas por nota al pie. Quedan dos límites, y el informe debe decirlo: (1) apoyo a la proposición — si una cita no citada textualmente realmente respalda la oración de la que cuelga — nunca se evalúa (eso es lo que significa existence-only); (2) las pincites se verifican solo cuando una cita textual las ancla. Trate existence-only como "fuente real, no leída", nunca como "aprobada".
Además, los problemas OBVIOS de FORMA (bloqueo de alcance levantado por el usuario, 2026-08-10 — «deshaga el bloqueo en la medida en que le impida verificar cosas obvias»). Una fase de Forma informa lo que se puede decidir solo a partir del borrador, sin consultar ninguna fuente:
- Formas cortas: una cita completa repetida dentro de la ventana de cinco notas al pie de la Regla 10.9 de Bluebook donde corresponde la forma corta; una forma corta de caso varada más allá de esa ventana o sin una cita completa antes en ningún lugar; una fuente secundaria citada completa dos veces cuando la Regla 4.2 exige
Autor, supra nota N. - Tipo de letra (solo
.docx): señales /Id./supra/quotingen redonda, lanota Ndespués de unsupraen cursiva incorrectamente en cursiva, cursivas que se extienden a la coma antes de una cita, versalitas rotas en medio de una palabra, y la cursivización del nombre del caso según la Regla 2.1(a) (redonda en una cita completa que se encuentra en una cláusula de cita, cursiva en una oración textual o forma corta — la única llamada que necesita un agente, ya que un patrón no puede distinguirlas).
Estas se ejecutan desde ${CLAUDE_PLUGIN_ROOT}/skills/legal-research/citeform.py, el mismo módulo que usa /proofread, por lo que las dos habilidades no pueden dar consejos contradictorios. Las reglas aplicadas están escritas en ${CLAUDE_PLUGIN_ROOT}/skills/legal-research/bluebook-typeface-and-short-forms.md. Los hallazgos de forma obtienen su propia sección de informe cerca del final y nunca entran en "Requiere su atención" — son de ordenación, no de fondo.
Lo que AÚN NO es: un linter completo de Bluebook (el orden de señales, el orden de citas, y si una cita está correctamente compuesta siguen fuera del alcance), un editor sustantivo, o un sustituto de la verificación de citas de la revista. La división con /proofread no cambia para todo lo demás: proofread lee la prosa, cite-check verifica las autoridades — ahora resulta que comparten la capa de formato de citas.
Cómo ejecutar
1. Analizar la solicitud
- draftPath — ruta al borrador (obligatorio).
.docxcon notas al pie reales de Word es canónico;.md/.txtcon notas al pie estilo pandoc[^n]funciona como alternativa. - footnotes — pase parcial opcional, ej. "notas al pie 45–80" o una lista. Por defecto: todo el borrador.
- deep — opcional; verificación más exhaustiva (agentes de verificación de esfuerzo medio, límite flexible más alto). Actívelo para un borrador casi final o cuando el usuario diga "deep"/"thorough".
- Si el borrador tiene cambios controlados, dígalo y pregunte si se deben aceptar todos antes de verificar (el analizador lee el texto actual/aceptado y omite las eliminaciones controladas, pero un borrador muy marcado merece un aviso).
1b. Preguntar qué profundidad usar (decisión del autor, 2026-08-09 — refleja /proofread paso 1b)
A menos que la solicitud ya lo resuelva, PREGUNTE de antemano — una AskUserQuestion, encabezado Profundidad, antes de la verificación previa. Incluya el aviso de cambios controlados (paso 1) en la misma llamada cuando corresponda, para que el usuario responda todo en una interacción en lugar de ser detenido dos veces.
Omita la pregunta cuando la redacción ya seleccione un nivel ("deep", "thorough", "near-final", "pre-submission", "quick", "standard"), en una re-ejecución parcial de un nivel ya elegido en esta sesión, o cuando el usuario haya solicitado solo un rango de notas al pie estrecho.
Dos opciones — cite-check no tiene una escalada fable, por lo que la escalera es más corta que la de proofread:
| Opción | Args | Qué decir |
|---|---|---|
| Estándar | deep:false | Agentes de verificación con bajo esfuerzo, límite flexible de 650k. Bueno para un borrador en curso. |
| Profundo | deep:true | Agentes de verificación con esfuerzo medio, límite flexible de 900k. Lectura más detallada de cada cita textual contra su fuente — para un borrador casi final. |
NO reutilice la justificación de /proofread aquí — los dos deep son mecanismos diferentes. Proofread's deep añade un segundo pase de extracción de desplazamiento (una jugada de recuperación, respaldada por el hallazgo de superposición del ~75–80% del mismo modelo). Cite-check's deep no añade un pase ni vuelve a obtener nada: eleva el esfuerzo del agente de verificación de low a medium (línea 557 del flujo de trabajo) y levanta el límite flexible. Compra cuidado por cita textual, no más citas textuales. La cobertura de citas textuales es idéntica de cualquier manera — cada cita textual se verifica en ambos niveles — así que no implique que el Estándar se salta algo.
El tiempo importa menos aquí que en proofread (deep no cambia la extracción, por lo que una re-ejecución posterior puede reproducir segmento/existencia desde el caché a través de resumeFromRunId), pero la verificación es la parte costosa de la ejecución — 26 de 33 agentes en el borrador National Muffler — por lo que un cambio de nivel aún significa volver a ejecutar la etapa cara. Pregunte primero.
2. Verificación previa (haga esto ANTES de lanzar — un aviso de permiso a mitad de ejecución puede matar un agente)
- Lea
~/.claude/settings.json; asegúrese de quepermissions.allowcontenga"WebFetch"y"WebSearch"(combine lo que falte — nunca reemplace el array). Configuración rutinaria; no pregunte. - Confirme que el token de CourtListener funciona. Pruébelo, no busque un archivo — ejecute
python3 ${CLAUDE_PLUGIN_ROOT}/skills/legal-research/check_cite.py "347 U.S. 483"; salida 0 con"found": truesignifica que funciona y no hay nada que informar.check_cite.pyresuelve el token desdeCOURTLISTENER_API_TOKEN, luegoCOURTLISTENER_TOKEN, luego el archivo~/.config/courtlistener/token— en ese orden, y la ruta de la variable de entorno (comúnmente establecida en el bloqueenvde~/.claude/settings.json) es la instalación normal, por lo que un directorio~/.config/courtlistener/faltante no prueba nada. Si la sonda realmente falla, la ejecución aún funciona (la existencia del caso recurre a la web), pero menciónelo una vez al momento de la entrega. Página del token: https://www.courtlistener.com/profile/api-token/ - Resuelva la biblioteca Zotero del proyecto (los proyectos difieren — algunas son bibliotecas grupales coautoradas, otras trabajo de biblioteca personal individual):
a. Busque una línea
Zotero library:en el archivoCLAUDE.md(oAGENTS.md) de la carpeta del proyecto. Si está presente, use el servidor MCP que nombra y vaya a (c). b. Si está ausente, PREGUNTE al usuario qué biblioteca Zotero usa este proyecto (biblioteca personal, o una biblioteca grupal con nombre), luego registre la respuesta como una líneaZotero library: <nombre> → MCP server <servidor>en el archivoCLAUDE.mdde la carpeta del proyecto para que las ejecuciones futuras no vuelvan a preguntar. c. Confirme que ese servidor MCP realmente existe (personal =zotero; las bibliotecas grupales tienen su propio servidor, ej.zotero-grouppara "5A general law", ID de grupo en~/.claude.json). Si la biblioteca del proyecto AÚN NO tiene servidor, ESTE es el momento de ofrecer añadir uno: duplique la entradazoteroen~/.claude.jsonbajozotero-<slug>conZOTERO_LIBRARY_TYPE=groupy elZOTERO_LIBRARY_IDdel grupo (encuéntrelo a través de la URL del grupo en zotero.org o los códigos de campo del borrador); tenga en cuenta que necesita un reinicio de Claude Code, por lo que los agentes recurren a la web en esta ejecución. d. Pase el nombre del servidor comozoteroServer(yzotero:falsesi no hay un servidor utilizable en esta ejecución).
2b. Instantánea del borrador (siempre)
Un archivo OneDrive/Word coautorado en vivo puede cambiar entre la extracción y la entrega, lo que haría que el informe describa bytes que nunca se verificaron. Copie el borrador una vez, proteja la copia contra escritura, aplique un hash, y ejecute todo lo posterior desde la instantánea. La ruta original se usa aquí y en ningún otro lugar — nunca en args del flujo de trabajo o un aviso de agente.
cp "<rutaBorrador>" "<scratch>/snapshot.docx" && chmod a-w "<scratch>/snapshot.docx"
shasum -a 256 "<scratch>/snapshot.docx" # registre esto; va en el pie del informe
3. Extraer y preparar (scripts deterministas — ejecútelos usted mismo, casi cero tokens)
Coloque el JSON intermedio en algún lugar donde los agentes del flujo de trabajo puedan leerlo (el bloc de notas de la sesión está bien). Use las rutas de script instaladas para que esto funcione desde cualquier carpeta (draftName sigue siendo el nombre de archivo original, no "snapshot"):
python3 ${CLAUDE_PLUGIN_ROOT}/skills/cite-check/scripts/extract_cites.py "<scratch>/snapshot.docx" "<scratch>/extract.json"
python3 ${CLAUDE_PLUGIN_ROOT}/skills/cite-check/scripts/prepare_units.py "<scratch>/extract.json" "<scratch>/units.json"
python3 ${CLAUDE_PLUGIN_ROOT}/skills/cite-check/scripts/citation_ledger.py "<scratch>/extract.json" "<scratch>/ledger.json"
python3 ${CLAUDE_PLUGIN_ROOT}/skills/cite-check/scripts/citation_ledger.py "<scratch>/extract.json" --compact > "<scratch>/ledger_args.json"
citation_ledger.py imprime instance_count / by_kind / unique_secondary_cites / unresolved_xrefs. Eche un vistazo a by_kind: un recuento grande de other o text significa que las notas al pie usan una forma de cita que el divisor no reconoce — esas instancias aún viajan en el libro mayor (como unchecked / not-a-citation), por lo que el informe se mantiene honesto, pero dígalo al momento de la entrega. El archivo --compact contiene las dos matrices que toma el flujo de trabajo (instances, secondary).
extract_cites.py imprime un resumen (footnote_count, body/footnote quote counts, unique_case_cite_count, supra_problem_candidates, más form_findings / form_short_form / form_typeface / formatting_available / case_name_candidates de la capa de forma). prepare_units.py imprime unit_count / case_cites / supra_problems. Lea extract.json para extraer las matrices que necesita el flujo de trabajo: unique_case_cites, supra_problem_candidates, y todo el bloque form_checks.
formatting_available: false significa un borrador en markdown/texto plano — las formas cortas aún se ejecutan, el tipo de letra no; dígalo al momento de la entrega. Si aparece formatting_unaligned_footnotes, esa cantidad de notas al pie no recibió análisis de tipo de letra (su texto formateado no coincidió con el texto del analizador validado, por lo que la capa declinó en lugar de arriesgarse a desplazamientos desalineados) — menciónelo solo si el recuento es no trivial. Para un pase parcial, resuelva el rango de notas al pie a identificadores de unidad:
python3 ${CLAUDE_PLUGIN_ROOT}/skills/cite-check/scripts/prepare_units.py "<scratch>/extract.json" --footnotes 45-80
(imprime unit_ids — páselos como unitIds).
4. Lanzar el flujo de trabajo
FlujoTrabajo({
scriptPath: "${CLAUDE_PLUGIN_ROOT}/skills/cite-check/cite-check.workflow.js",
args: {
skillsDir: "${CLAUDE_PLUGIN_ROOT}/skills", // donde residen los scripts auxiliares empaquetados
extractPath: "<scratch>/extract.json", // los agentes leen unidades + contexto completo desde aquí
draftName: "<nombre de archivo del borrador sin extensión>",
footnoteCount: <extract.footnote_count>,
unitCount: <prepare.unit_count>,
caseCites: <extract.unique_case_cites>, // array
supraProblems: <extract.supra_problem_candidates>, // array
formChecks: <extract.form_checks>, // tipo de letra + formas cortas (bloque completo)
ledger: <ledger_args.instances>, // cada instancia de cita (forma compacta)
secondaryCites:<ledger_args.secondary>, // fuentes secundarias únicas no citadas textualmente
unitIds: <null | [ids from --footnotes]>, // solo pase parcial
deep: false,
zotero: true, // false si no hay un servidor Zotero utilizable en esta ejecución
zoteroServer: "<from pre-flight 2.3>" // ej. "zotero-group" (5A) o "zotero" (personal)
}
})
Pipeline (todas las etapas del modelo Sonnet excepto el informe, que hereda el modelo de la sesión):
- Segmentar/resolver — fragmentado; cada cita textual se empareja con la fuente ESPECÍFICA de la que cuelga, recorriendo las cadenas de
Id.hasta su antecedente real (que puede ser un caso dos notas atrás) y siguiendo las redirecciones desupra nota N, usando