Skip to content

Add ref-list validations for SPS 1.10 (rules 1-14)#1135

Draft
Copilot wants to merge 2 commits intomasterfrom
copilot/create-validations-ref-list
Draft

Add ref-list validations for SPS 1.10 (rules 1-14)#1135
Copilot wants to merge 2 commits intomasterfrom
copilot/create-validations-ref-list

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 19, 2026

O que esse PR faz?

Implementa 9 novas validações para <ref-list> conforme SPS 1.10 e Critérios SciELO Brasil, atingindo 14 de 20 regras (70%). As 5 regras restantes já existiam (mixed-citation, publication-type, source, year).

Novas validações:

  • Nível documento: presença de <ref-list> em docs indexáveis (exceto correction/retraction/addendum/expression-of-concern/reviewer-report), presença de <ref> em <ref-list>
  • Nível referência: presença de <element-citation>, máximo 1 <ext-link> em element-citation e mixed-citation, <lpage> obrigatório quando <fpage> existe, @units="pages" em <size>, @content-type="access-date" em <date-in-citation>, <surname> obrigatório em <name>

Também corrige null safety em get_publication_type() quando <element-citation> está ausente.

Onde a revisão poderia começar?

packtools/sps/validation/references.py — novos métodos em ReferenceValidation (regras per-ref) e ReferencesValidation (regras ref-list level).

Como este poderia ser testado manualmente?

from lxml import etree
from packtools.sps.validation.references import ReferencesValidation

xml = """<article xmlns:xlink="http://www.w3.org/1999/xlink"
  article-type="research-article" xml:lang="en">
  <front><article-meta>
    <pub-date date-type="pub"><year>2024</year></pub-date>
  </article-meta></front>
  <back>
    <ref-list>
      <ref id="B1">
        <mixed-citation>Author. Title. 2020.</mixed-citation>
        <element-citation publication-type="journal">
          <source>Journal</source><year>2020</year>
          <fpage>31</fpage><!-- missing lpage triggers ERROR -->
        </element-citation>
      </ref>
    </ref-list>
  </back>
</article>"""

tree = etree.fromstring(xml)
for r in ReferencesValidation(tree, {"publication_type_requires": {"journal": ["source","year"]}}).validate():
    if r["response"] != "OK":
        print(f'{r["response"]}: {r["title"]}{r["advice"]}')

Testes automatizados: python -m pytest tests/sps/validation/test_ref_list.py -v (42 testes).

Algum cenário de contexto que queira dar?

Arquivos modificados:

  • packtools/sps/models/references.py — 5 novos métodos de extração de dados (has_element_citation, ext_link_count_*, date_in_citation_content_type, names_without_surname)
  • packtools/sps/validation/references.py — 9 novos métodos de validação
  • packtools/sps/validation_rules/references_rules.json — 9 novos parâmetros de error level + lista de article types isentos
  • tests/sps/validation/test_ref_list.py — 42 novos testes (unitários + integração)
  • tests/sps/validation/test_references.py — ajuste em 1 teste que usava índice fixo (quebrou com novas validações, agora filtra por título)

Screenshots

N/A — validações backend sem componente visual.

Quais são tickets relevantes?

Criar validações para o elemento <ref-list>

Referências

Original prompt

This section details on the original issue you should resolve

<issue_title>Criar validações para o elemento </issue_title>
<issue_description>## Objetivo

Implementar validações para o elemento <ref-list> conforme a especificação SPS 1.10 e Critérios SciELO Brasil, aumentando a conformidade de X% para 70% (14 de 20 regras).

Nota: Algumas validações para <ref-list> podem já estar parcialmente implementadas no repositório. Este Issue visa reavaliar, complementar e garantir cobertura completa das regras SPS 1.10 e Critérios SciELO Brasil.


Contexto

O elemento <ref-list> representa o conjunto de referências bibliográficas de um documento. Para SciELO Brasil, é obrigatório em todos os documentos indexáveis (exceto errata, retratação, adendo, manifestação de preocupação e parecer). Cada referência deve conter <mixed-citation> (apresentação) e <element-citation> (dados estruturados para métricas). Validações corretas garantem conformidade com critérios SciELO Brasil, presença de elementos obrigatórios, e qualidade dos metadados bibliográficos.

Conformidade atual: X de 20 regras implementadas (X%)
Meta após implementação: 14 de 20 regras (70%)


Documentação SPS

Referência oficial: https://docs.google.com/document/d/1GTv4Inc2LS_AXY-ToHT3HmO66UT0VAHWJNOIqzBNSgA/edit?tab=t.0#heading=h.reflist

Regras principais conforme SPS 1.10 e Critérios SciELO Brasil:

  1. Ocorrência:

    • <ref-list> aparece em <back> uma ou mais vezes
    • Pode aparecer aninhado dentro de <ref-list>
  2. Obrigatoriedade (Critério SciELO Brasil):

    • <ref-list> é obrigatório em documentos indexáveis
    • Exceções: errata, retratação, adendo, manifestação de preocupação, parecer
  3. Estrutura obrigatória:

    • <ref-list> deve conter pelo menos um <ref>
    • <ref> deve conter <mixed-citation> E <element-citation>
  4. Atributo obrigatório em <element-citation>:

    • @publication-type (obrigatório)
  5. Valores permitidos para @publication-type:

    • book - Livros, capítulos de livros
    • confproc - Atas, anais, proceedings de eventos
    • data - Dados de pesquisa (datasets)
    • database - Bases de dados
    • journal - Artigos de periódicos científicos
    • legal-doc - Normas jurídicas
    • letter - Cartas e comunicações pessoais
    • newspaper - Artigos de jornal
    • patent - Patentes
    • preprint - Preprints
    • report - Relatórios técnicos
    • software - Software
    • thesis - Monografias, dissertações, teses
    • webpage - Sites, blogs
    • other - Tipos não previstos
  6. Restrições em <element-citation>:

    • Proibido: dois ou mais <ext-link>
    • Proibido: pontuação entre elementos (ponto, vírgula, etc.)
    • Proibido: <comment> abarcando apenas <ext-link>
    • Proibido: formatação completa em <italic> ou <bold>
  7. Restrições em <mixed-citation>:

    • Proibido: dois ou mais <ext-link>
    • Permitido apenas tags de formatação: <bold>, <italic>, <sup>, <sub>
  8. Elementos esperados em <element-citation>:

    • <source> - Título da fonte (esperado em todas as referências)
    • <year> - Ano (esperado em todas as referências)
  9. Regras de elementos específicos:

    • Quando há <fpage>, <lpage> é obrigatório
    • <size> deve ter @units="pages"
    • <date-in-citation> deve ter @content-type="access-date"
    • <person-group> deve ter @person-group-type quando presente
    • <name> dentro de <person-group> deve ter <surname>

Regras a Implementar

P0 – Críticas (implementar obrigatoriamente)

# Regra Nível Descrição
1 Validar presença de <ref-list> em documentos indexáveis CRITICAL <ref-list> é obrigatório em <back> para documentos indexáveis (exceto errata, retratação, adendo, manifestação de preocupação, parecer)
2 Validar presença de <ref> CRITICAL <ref-list> deve conter pelo menos um elemento <ref>
3 Validar presença de <mixed-citation> CRITICAL Cada <ref> deve conter <mixed-citation>
4 Validar presença de <element-citation> CRITICAL Cada <ref> deve conter <element-citation>
5 Validar presença de @publication-type CRITICAL O atributo @publication-type é obrigatório em <element-citation>
6 Validar valores permitidos de @publication-type ERROR O valor de @publication-type deve estar na lista de valores permitidos
7 Validar ausência de múltiplos <ext-link> em <element-citation> ERROR É proibida a ocorrência de dois ou mais <ext-link> em <element-citation>
8 Validar ausência de múltiplos <ext-link> em <mixed-citation> ERROR É proibida a ocorrência de dois ou mais <ext-link> em <mixed-citation>

P1 – Importantes (implementar se possível)

# Regra Nível Descrição
9 Validar pr...

📍 Connect Copilot coding agent with Jira, Azure Boards or Linear to delegate work to Copilot in one click without leaving your project management tool.

- Model: Add has_element_citation, ext_link counts, date_in_citation_content_type, names_without_surname
- Validation: Add validate_ref_list_presence, validate_ref_presence, validate_element_citation,
  validate_ext_link_count_*, validate_lpage_when_fpage, validate_size_units,
  validate_date_in_citation_content_type, validate_surname_in_name
- Rules: Add new error levels for all new validations
- Tests: 42 new tests in test_ref_list.py

Co-authored-by: robertatakenaka <505143+robertatakenaka@users.noreply.github.com>
Copilot AI changed the title [WIP] Implement validations for <ref-list> element Add ref-list validations for SPS 1.10 (rules 1-14) Mar 19, 2026
Copilot AI requested a review from robertatakenaka March 19, 2026 12:01
Copy link
Copy Markdown
Collaborator

@Rossi-Luciano Rossi-Luciano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Evidencia de revisao -- references.py

Data: 2026-04-23
Revisor: Luciano
Artefatos analisados:

  • references.py (validation) -- modulo de validacao
  • references.py (model) -- Reference, XMLReferences, FullTextReferences
  • references_rules.json -- parametros de configuracao
  • references.xml -- XML artificial gerado para cobertura de testes
  • references-2026-23-04-133123-errors.csv -- relatorio de erros gerado pelo packtools

Metodologia

Análise cruzada entre o modulo .py, o XML artificial construído com o princípio do defeito isolado (um defeito por caso de teste), e o relatório CSV produzido pelo processamento do XML pelo packtools. Para cada caso documentado no XML verificou-se: se o módulo deveria disparar o erro (leitura das regras do código), se o CSV contem a entrada correspondente, se o nível de severidade está correto, e se casos válidos estão corretamente ausentes do CSV.

O módulo expõe duas classes: ReferencesValidation (nível de artigo, 2 regras) e
ReferenceValidation (por referência, 17 regras). O citing_pub_year e extraído de FulltextDates.collection_date ou article_date do artigo hospedeiro (ano 2024).


Regras validadas (19 no total)

# Classe Método Nível configurado
R1 ReferencesValidation validate_ref_list_presence CRITICAL
R2 ReferencesValidation validate_ref_presence CRITICAL
R3 ReferenceValidation validate_element_citation CRITICAL
R4 ReferenceValidation validate_mixed_citation CRITICAL
R5 ReferenceValidation validate_year CRITICAL
R6 ReferenceValidation validate_source CRITICAL
R7 ReferenceValidation validate_publication_type CRITICAL
R8 ReferenceValidation validate_article_title ERROR
R9 ReferenceValidation validate_authors ERROR
R10 ReferenceValidation validate_comment_is_required_or_not ERROR
R11 ReferenceValidation validate_mixed_citation_sub_tags CRITICAL
R12 ReferenceValidation validate_title_tag_by_dtd_version CRITICAL
R13 ReferenceValidation validate_not_marked WARNING
R14 ReferenceValidation validate_ext_link_count_element_citation ERROR
R15 ReferenceValidation validate_ext_link_count_mixed_citation ERROR
R16 ReferenceValidation validate_lpage_when_fpage ERROR
R17 ReferenceValidation validate_size_units ERROR
R18 ReferenceValidation validate_date_in_citation_content_type ERROR
R19 ReferenceValidation validate_surname_in_name ERROR

Casos de teste no XML artificial (19 referencias)

Caso Ref Defeito introduzido Nivel esperado
P1 B01 Nenhum -- caso ouro journal completo OK
C-R3 B02 <element-citation> ausente CRITICAL
C-R4 B03 <mixed-citation> ausente CRITICAL
C-R5a B04 <year>=2099 > citing_pub_year=2024 CRITICAL
C-R5b B05 <year> ausente (year=None, TypeError) CRITICAL
C-R6 B06 <source> ausente em journal CRITICAL
C-R7 B07 @publication-type="unknown" invalido CRITICAL
C-R8 B08 <article-title> ausente em journal ERROR
C-R9 B09 <person-group> ausente em journal ERROR
C-R10 B10 Texto tail antes de <ext-link> sem <comment> (cenario 3) ERROR
C-R11 B11 <underline> (tag proibida) em <mixed-citation> CRITICAL
C-R12 B12 <chapter-title> em book (condicional: dtd-version >= 1.3) CRITICAL
C-R13 B13 Texto >20 chars em <mixed-citation> nao marcado WARNING
C-R14 B14 2 <ext-link> em <element-citation> ERROR
C-R15 B15 2 <ext-link> em <mixed-citation> ERROR
C-R16 B16 <fpage> presente sem <lpage> ERROR
C-R17 B17 <size units="chapters"> (invalido) ERROR
C-R18 B18 <date-in-citation content-type="update-date"> ERROR
C-R19 B19 <name> sem <surname> em <person-group> ERROR

Não testáveis neste XML (requerem XMLs separados): C-R1 (<ref-list> ausente) e
C-R2 (<ref-list> sem <ref>).


Resultado da verificação cruzada com o CSV

Entradas corretas do módulo references.py

Ref Regra Nível Verificação
B02 R3 CRITICAL PASS -- element-citation ausente
B02 R5 CRITICAL PASS -- cascata: year=None, TypeError
B02 R6 CRITICAL PASS -- cascata: source=None
B02 R7 CRITICAL PASS -- cascata: publication_type=None
B02 R13 WARNING PASS -- cascata: mixed-citation nao marcada (>20 chars)
B03 R4 CRITICAL PASS -- mixed-citation ausente
B04 R5 CRITICAL PASS -- year=2099 > 2024
B05 R5 CRITICAL PASS -- year=None
B06 R6 CRITICAL PASS -- source ausente
B07 R7 CRITICAL PASS -- publication-type="unknown"
B08 R8 ERROR PASS -- article-title ausente
B09 R9 ERROR PASS -- person-group ausente
B10 R10 ERROR PASS -- cenario 3: text_before_extlink="Disponivel em: "
B11 R11 CRITICAL PASS -- tag "underline" em mixed-citation
B13 R13 WARNING PASS -- "Informacao extra nao mapeada" (48 chars)
B14 R14 ERROR PASS -- 2 ext-links em element-citation
B15 R15 ERROR PASS -- 2 ext-links em mixed-citation
B16 R16 ERROR PASS -- fpage=55 sem lpage
B17 R17 ERROR PASS -- size units="chapters"
B18 R18 ERROR PASS -- date-in-citation content-type="update-date"

Falso negativo identificado

Ref Regra Nível Situação Causa
B19 R19 ERROR FALSO NEGATIVO XML usa tag <n> nos autores; o model usa XPath .//name. O validador nao encontra nenhum <name> portanto names_without_surname=[] e R19 nao dispara. Correcao: substituir <n> por <name> em todo o XML.

Regra condicional confirmada

Ref Regra Nível Situacao
B12 R12 CRITICAL NAO DISPAROU: dtd_version padrao e "1.1" (de get_default_params); a regra exige >= 1.3. Se o sistema repassar dtd-version="1.3" do elemento raiz para params, R12 dispararia. Comportamento condicional confirmado conforme documentado no XML.

Falsos positivos em cascata (defeito no XML, nao no modulo)

Todas as referências com <person-group> no XML usam a tag <n> em vez de <name>.
O model (get_all_authors) usa XPath .//name, portanto all_authors=[] em todos os casos. Isso fez R9 disparar para B01 (caso ouro), B03, B04, B05, B06, B08, B11, B12, B13, B16 e B17 -- todos indevidamente. Trata-se de defeito no XML artificial, não no módulo. A correção é substituir <n> por <name> em todas as referências.


Conclusão sobre o módulo references.py

O módulo references.py está correto para todas as regras verificáveis neste XML.
As 20 entradas esperadas do módulo apareceram no CSV com os niveis corretos. O falso negativo em R19 e o falso positivo em R9 são consequências de defeito no XML artificial (uso de <n> em vez de <name>), e não de bug no modulo. R12 e confirmado como condicional ao valor de dtd_version em params.


Ruído identificado (outros módulos)

Entradas no CSV não relacionadas ao references.py, classificadas como ruído esperado:

Estrutural (XML artificial mínimo): abstract, history dates, subject/subj-group,
fig, table-wrap, disp-formula, inline-formula, app ausentes.

Ambiente local: rendition PDF não encontrado, DOI nao registrado no Crossref, issue não verificada no Core.

Novos tipos de ruído identificados nesta sessão (a incorporar como padrao):

  1. id and rid ERROR (19 entradas): cada <ref> sem <xref ref-type="bibr"> correspondente no body gera um ERROR. Para XMLs artificiais de referências, adicionar <xref> fictícios no body ou aceitar este ruído.
  2. ext-link WARNING (9 entradas): todo <ext-link> cujo texto é uma URL sem
    @xlink:title gera WARNING. Para XMLs artificiais, adicionar xlink:title="..." a
    todos os <ext-link>, ou aceitar este ruído.

Problema com testes unitários (test_references.py):

======================================================================================== short test summary info =========================================================================================
FAILED tests/sps/validation/test_references.py::ReferenceValidationTest::test_validate_mixed_citation_sub_tags_disallowed - AssertionError: "remove ['ext-link', 'u'] from mixed-citation" != "remove ['u', 'ext-link'] from mixed-citation"
FAILED tests/sps/validation/test_references.py::ReferenceValidationTest::test_validate_publication_type_fail_invalid - AssertionError: ['book'] != "one of ['book']"
====================================================================================== 2 failed, 13 passed in 0.46s ======================================================================================

@robertatakenaka
Copy link
Copy Markdown
Member

@copilot corrigir os testes ======================================================================================== short test summary info =========================================================================================
FAILED tests/sps/validation/test_references.py::ReferenceValidationTest::test_validate_mixed_citation_sub_tags_disallowed - AssertionError: "remove ['ext-link', 'u'] from mixed-citation" != "remove ['u', 'ext-link'] from mixed-citation"
FAILED tests/sps/validation/test_references.py::ReferenceValidationTest::test_validate_publication_type_fail_invalid - AssertionError: ['book'] != "one of ['book']"
====================================================================================== 2 failed, 13 passed in 0.46s ======================

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Criar validações para o elemento <ref-list>

3 participants