Add <response> element validation for SPS 1.10 compliance#1138
Add <response> element validation for SPS 1.10 compliance#1138
Conversation
Implements 7 validation rules for <response> element: - Rule 1: @response-type presence (CRITICAL) - Rule 2: @response-type value must be "reply" (ERROR) - Rule 3: @xml:lang presence (CRITICAL) - Rule 4: @id presence (CRITICAL) - Rule 5: @id uniqueness (ERROR) - Rule 6: <front-stub> presence (WARNING) - Rule 7: <body> presence (WARNING) New files: - packtools/sps/validation/response.py - Validation class - packtools/sps/validation_rules/response_rules.json - Rules config - tests/sps/validation/test_response.py - 31 unit tests Modified files: - packtools/sps/validation/xml_validations.py - Import + wrapper function - packtools/sps/validation/xml_validator.py - Orchestrator integration Co-authored-by: robertatakenaka <505143+robertatakenaka@users.noreply.github.com>
Co-authored-by: robertatakenaka <505143+robertatakenaka@users.noreply.github.com>
Rossi-Luciano
left a comment
There was a problem hiding this comment.
Evidência de revisão — response.py
Data: 2026-04-25
Revisor: Luciano
Artefatos analisados:
response.py(validation) — módulo de validação (ResponseValidation)response_rules.json— parâmetros de configuraçãoresponse.xml— XML artificial gerado para cobertura de testesresponse-2026-25-04-145722-errors.csv— relatório de erros gerado pelo packtools
Metodologia
Análise cruzada entre o módulo de validação, o JSON de regras, o XML artificial
construído com o princípio do defeito isolado e o relatório CSV. O módulo é autocontido: _get_response_elements() extrai todos os campos diretamente do nó XML via XPath e .get(), sem delegar a nenhuma classe de model externa. Não foi necessário solicitar um módulo de model adicional.
O XML usa article-type="letter", que não consta em data_availability_required_article_types, evitando ruído do validador de disponibilidade de dados nas seções.
Regras validadas (7 métodos)
| # | Método | Nível configurado |
|---|---|---|
| R1 | validate_response_type_presence |
CRITICAL |
| R2 | validate_response_type_value |
ERROR |
| R3 | validate_xml_lang_presence |
CRITICAL |
| R4 | validate_id_presence |
CRITICAL |
| R5 | validate_id_uniqueness |
ERROR |
| R6 | validate_front_stub_presence |
WARNING |
| R7 | validate_body_presence |
WARNING |
Casos de teste no XML artificial (9 elementos <response>)
| Caso | Defeito introduzido | Nível esperado | Isolamento |
|---|---|---|---|
| P1 | Nenhum — caso ouro completo | OK (ausente do CSV) | todos os atributos e filhos válidos |
| C-R1 | <response> sem @response-type |
CRITICAL | R2 skipa (if not response_type: continue) — sem cascata |
| C-R2 | @response-type="comment" (valor inválido) |
ERROR | R1 passa (bool("comment")=True) |
| C-R3 | <response> sem @xml:lang |
CRITICAL | demais atributos válidos |
| C-R4 | <response> sem @id |
CRITICAL | R5 skipa (if not response_id: continue) — sem cascata |
| C-R5a | @id="resp-dup" (1ª ocorrência) |
ERROR | todos os outros atributos válidos para isolar R5 |
| C-R5b | @id="resp-dup" (2ª ocorrência) |
ERROR | validate_id_uniqueness percorre todos os contextos e gera uma entrada por instância duplicada |
| C-R6 | <response> sem <front-stub> |
WARNING | demais atributos e <body> válidos |
| C-R7 | <response> sem <body> |
WARNING | demais atributos e <front-stub> válidos |
Verificação cruzada com o CSV
Todas as 8 entradas esperadas do módulo response.py aparecem no CSV sob o
subject response, com os níveis de severidade corretos:
| Subject | Caso | Nível | Verificação |
|---|---|---|---|
| response | C-R1 | CRITICAL | PASS — response @response-type presence |
| response | C-R2 | ERROR | PASS — Replace @response-type with "reply" |
| response | C-R3 | CRITICAL | PASS — response @xml:lang presence |
| response | C-R4 | CRITICAL | PASS — response @id presence |
| response | C-R5a | ERROR | PASS — Replace duplicate @id="resp-dup" (1ª instância) |
| response | C-R5b | ERROR | PASS — Replace duplicate @id="resp-dup" (2ª instância) |
| response | C-R6 | WARNING | PASS — response front-stub presence |
| response | C-R7 | WARNING | PASS — response body presence |
O caso ouro P1 não gera nenhuma entrada. Não foram identificados falsos positivos nem falsos negativos originados do módulo.
Nota sobre R5: validate_id_uniqueness coleta todos os contextos em uma única passagem, identifica os ids duplicados e gera uma entrada por instância. O resultado de 2 entradas para @id="resp-dup" é o comportamento esperado e correto.
Ruído identificado (outros módulos) — 20 entradas
Ruído estrutural (XML artificial mínimo): history dates ausentes (5 entradas),
subject/subj-group heading ausente (3 entradas), disp-formula, inline-formula, table-wrap e app ausentes, bibliographic strip incompleto.
Ruído de ambiente: rendition PDF ausente, article dates incompleto, DOI não
registrado no Crossref.
Ruído de referência (id and rid ERROR, 1 entrada): <ref id="B01"> presente no
<ref-list> sem <xref ref-type="bibr" rid="B01"> correspondente no corpo do
artigo. Para eliminar esse ruído nos próximos XMLs artificiais de módulos que não validam referências, incluir ao menos um <xref ref-type="bibr" rid="B01"> no corpo.
Ruído de open science (CRITICAL, 1 entrada): o validador de open science disparou mesmo para article-type="letter". Verificar se letter deveria estar isento da exigência de declaração de disponibilidade de dados nesse módulo.
Conclusão
O módulo response.py está correto. Todas as 8 entradas esperadas dispararam com os níveis de severidade corretos, sem falsos positivos nem falsos negativos originados do módulo. O comportamento de skip de R2 para response_type=None (C-R1) e de skip de R5 para id=None (C-R4) foi confirmado pela ausência de cascatas no CSV.
O que esse PR faz?
Implementa 7 regras de validação para o elemento
<response>conforme SPS 1.10, cobrindo atributos obrigatórios, unicidade de IDs e estrutura mínima esperada.@response-typepresença@response-typevalor ="reply"@xml:langpresença@idpresença@idunicidade<front-stub>presença<body>presençaOnde a revisão poderia começar?
packtools/sps/validation/response.py— contém a classeResponseValidationcom todos os 7 métodos de validação.Como este poderia ser testado manualmente?
Testar também via orchestrator:
31 testes unitários em
tests/sps/validation/test_response.pycobrem: atributos ausentes/vazios/whitespace, valores incorretos, IDs duplicados, respostas em<sub-article>, error levels customizáveis.Algum cenário de contexto que queira dar?
O
<response>identifica respostas a cartas/comentários publicadas no mesmo documento. Segue o mesmo padrão arquitetural dos validadores existentes (HistoryValidation,XMLPeerReviewValidation): classe de validação + rules JSON + integração no orchestrator viaxml_validations.py/xml_validator.py.Arquivos criados:
packtools/sps/validation/response.py—ResponseValidationpacktools/sps/validation_rules/response_rules.json— configuração de níveis de errotests/sps/validation/test_response.py— 31 testesArquivos modificados:
packtools/sps/validation/xml_validations.py— import +validate_response()packtools/sps/validation/xml_validator.py— yield do grupo"response"Screenshots
N/A — validação backend sem componente visual.
Quais são tickets relevantes?
Referências
<response>Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
api.crossref.orgfrom lxml import etree
from packtools.sps.validation.xml_validator import get_validation_results
from packtools.sps.validation.xml_validator_rules import get_default_rules
Test that response_rules loads from the JSON
rules = get_default_rules()
assert` (dns block)
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
<response>conforme a especificação SPS 1.10, aumentando a conformidade de X% para 70% (7 de 10 regras).Nota: Algumas validações para
<response>podem já estar parcialmente implementadas no repositório. Este Issue visa reavaliar, complementar e garantir cobertura completa das regras SPS 1.10.Contexto
O elemento
<response>identifica um conjunto de respostas referente a uma carta ou comentário, obrigatoriamente publicadas juntamente com a carta/comentário. É usado quando há múltiplas respostas no mesmo documento. Validações corretas garantem presença de atributos obrigatórios, unicidade de IDs, e estrutura mínima necessária.Conformidade atual: X de 10 regras implementadas (X%)
Meta após implementação: 7 de 10 regras (70%)
Documentação SPS
Referência oficial: https://docs.google.com/document/d/1GTv4Inc2LS_AXY-ToHT3HmO66UT0VAHWJNOIqzBNSgA/edit?tab=t.0#heading=h.response
Regras principais conforme SPS 1.10:
Ocorrência:
<response>pode aparecer zero ou mais vezes em<article>e<sub-article>Contexto de uso:
<sub-article article-type="reply"><article article-type="reply">Atributos obrigatórios:
@response-type="reply"(obrigatório)@xml:lang(obrigatório)@id(obrigatório)Unicidade de IDs:
@iddiferente para cada<response>Estrutura esperada:
<front-stub>- Metadados da resposta<body>- Conteúdo da resposta<back>- Seção final (opcional, pode conter<ref-list>)Regras a Implementar
P0 – Críticas (implementar obrigatoriamente)
@response-type@response-typeé obrigatório em<response>@response-type@response-typedeve ser"reply"@xml:lang@xml:langé obrigatório em<response>@id@idé obrigatório em<response>@id<response>deve ter um@idúnico (não pode repetir valores)P1 – Importantes (implementar se possível)
<front-stub><response>contenha<front-stub>com metadados da resposta<body><response>contenha<body>com o conteúdo da respostaP2 – Futuras (fora do escopo deste Issue)
Arquivos a Criar/Modificar
Avaliar existentes (podem ter validações parciais):
packtools/sps/models/response.pyou similar – Verificar se modelo existepacktools/sps/validation/response.py– Verificar validações existentespacktools/sps/validation/rules/response_rules.jsonou similar – Verificar configuraçãoCriar (se não existirem):
packtools/sps/models/response.py– Modelo de extração de dadospacktools/sps/validation/response.py– Validaçõespacktools/sps/validation/rules/response_rules.json– Configuração de níveis de errotests/sps/validation/test_response.py– Testes unitáriosReferenciar (implementações similares):
packtools/sps/validation/sub_article.py– Validação de estrutura similarpacktools/sps/validation/utils.py– Funções auxiliares (build_response)Exemplos de XML
XML Válido (deve passar sem erros):