Add ref-list validations for SPS 1.10 (rules 1-14)#1135
Add ref-list validations for SPS 1.10 (rules 1-14)#1135
Conversation
- 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>
Rossi-Luciano
left a comment
There was a problem hiding this comment.
Evidencia de revisao -- references.py
Data: 2026-04-23
Revisor: Luciano
Artefatos analisados:
references.py(validation) -- modulo de validacaoreferences.py(model) --Reference,XMLReferences,FullTextReferencesreferences_rules.json-- parametros de configuracaoreferences.xml-- XML artificial gerado para cobertura de testesreferences-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):
id and ridERROR (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.ext-linkWARNING (9 entradas): todo<ext-link>cujo texto é uma URL sem
@xlink:titlegera WARNING. Para XMLs artificiais, adicionarxlink: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 ======================================================================================
|
@copilot corrigir os testes ======================================================================================== short test summary info ========================================================================================= |
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:
<ref-list>em docs indexáveis (exceto correction/retraction/addendum/expression-of-concern/reviewer-report), presença de<ref>em<ref-list><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 emReferenceValidation(regras per-ref) eReferencesValidation(regras ref-list level).Como este poderia ser testado manualmente?
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çãopacktools/sps/validation_rules/references_rules.json— 9 novos parâmetros de error level + lista de article types isentostests/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:
Ocorrência:
<ref-list>aparece em<back>uma ou mais vezes<ref-list>Obrigatoriedade (Critério SciELO Brasil):
<ref-list>é obrigatório em documentos indexáveisEstrutura obrigatória:
<ref-list>deve conter pelo menos um<ref><ref>deve conter<mixed-citation>E<element-citation>Atributo obrigatório em
<element-citation>:@publication-type(obrigatório)Valores permitidos para
@publication-type:book- Livros, capítulos de livrosconfproc- Atas, anais, proceedings de eventosdata- Dados de pesquisa (datasets)database- Bases de dadosjournal- Artigos de periódicos científicoslegal-doc- Normas jurídicasletter- Cartas e comunicações pessoaisnewspaper- Artigos de jornalpatent- Patentespreprint- Preprintsreport- Relatórios técnicossoftware- Softwarethesis- Monografias, dissertações, teseswebpage- Sites, blogsother- Tipos não previstosRestrições em
<element-citation>:<ext-link><comment>abarcando apenas<ext-link><italic>ou<bold>Restrições em
<mixed-citation>:<ext-link><bold>,<italic>,<sup>,<sub>Elementos esperados em
<element-citation>:<source>- Título da fonte (esperado em todas as referências)<year>- Ano (esperado em todas as referências)Regras de elementos específicos:
<fpage>,<lpage>é obrigatório<size>deve ter@units="pages"<date-in-citation>deve ter@content-type="access-date"<person-group>deve ter@person-group-typequando presente<name>dentro de<person-group>deve ter<surname>Regras a Implementar
P0 – Críticas (implementar obrigatoriamente)
<ref-list>em documentos indexáveis<ref-list>é obrigatório em<back>para documentos indexáveis (exceto errata, retratação, adendo, manifestação de preocupação, parecer)<ref><ref-list>deve conter pelo menos um elemento<ref><mixed-citation><ref>deve conter<mixed-citation><element-citation><ref>deve conter<element-citation>@publication-type@publication-typeé obrigatório em<element-citation>@publication-type@publication-typedeve estar na lista de valores permitidos<ext-link>em<element-citation><ext-link>em<element-citation><ext-link>em<mixed-citation><ext-link>em<mixed-citation>P1 – Importantes (implementar se possível)
📍 Connect Copilot coding agent with Jira, Azure Boards or Linear to delegate work to Copilot in one click without leaving your project management tool.