Add <sec> element validation (SPS 1.10, 7/10 rules)#1137
Add <sec> element validation (SPS 1.10, 7/10 rules)#1137
<sec> element validation (SPS 1.10, 7/10 rules)#1137Conversation
Implements validation for <sec> elements: - Rule 1: <title> presence (CRITICAL) - Rule 2: @sec-type valid values (ERROR) - Rule 3: @id for transcript sections (ERROR) - Rule 4: data-availability section for indexable articles (ERROR) - Rule 5: Combined sec-type pipe format (WARNING) - Rule 6: Non-combinable sec-types (WARNING) - Rule 7: Content presence (WARNING) New files: - packtools/sps/models/sec.py - Model for <sec> data extraction - packtools/sps/validation/sec.py - Validation logic - packtools/sps/validation_rules/sec_rules.json - Rules config - tests/sps/validation/test_sec.py - 29 unit tests Modified files: - packtools/sps/validation/xml_validations.py - Added validate_secs() - packtools/sps/validation/xml_validator.py - Added sec group Co-authored-by: robertatakenaka <505143+robertatakenaka@users.noreply.github.com>
<sec> element validation (SPS 1.10, 7/10 rules)
Rossi-Luciano
left a comment
There was a problem hiding this comment.
Evidência de revisão — sec.py
Data: 2026-04-24
Revisor: Luciano
Artefatos analisados:
sec.py(validation) — módulo de validação (SecValidation,XMLSecValidation)sec.py(model) —ArticleSecs,Secsec_rules.json— parâmetros de configuraçãosec.xml— XML artificial gerado para cobertura de testessec-2026-24-04-120514-errors.csv— relatório de erros gerado pelo packtools
Metodologia
Análise cruzada entre os dois módulos de mesmo nome (sec.py de validation e de models), o JSON de regras, o XML artificial construído com o princípio do defeito isolado, e o relatório CSV. O model foi necessário para confirmar três pontos: (1) paragraph_count usa element.findall("p") — apenas <p> filhos diretos, não descendentes; (2) all_secs usa .//sec — inclui subsecções aninhadas, cada uma validada individualmente; (3) body_sec_types usa body.findall("sec") — apenas filhos diretos de <body>, uma <sec sec-type="data-availability"> aninhada não satisfaz a regra R4.
Para evitar ruído de R7 causado por subsecções sem <p> direto, todas as seções de teste foram posicionadas como irmãs de primeiro nível em <body>, sem subsecções.
Regras validadas (7 em SecValidation + 1 em XMLSecValidation)
| # | Classe | Método | Nível configurado |
|---|---|---|---|
| R1 | SecValidation | validate_title |
CRITICAL |
| R2 | SecValidation | validate_sec_type_value |
ERROR |
| R3 | SecValidation | validate_transcript_id |
ERROR |
| R4 | XMLSecValidation | validate_data_availability_presence |
ERROR |
| R5 | SecValidation | validate_combined_format |
WARNING |
| R6 | SecValidation | validate_non_combinable |
WARNING |
| R7 | SecValidation | validate_content |
WARNING |
Casos de teste no XML artificial
| Caso | Defeito introduzido | Nível esperado | Isolamento |
|---|---|---|---|
| P1 | Nenhum — caso ouro, sec-type="intro" com <title> e <p> |
OK (ausente do CSV) | todos os métodos passam |
| C-R1 | <sec> sem <title> |
CRITICAL | sec_type=None — R2, R3, R5, R6 retornam None (skip); R7 passa (tem <p>) |
| C-R2 | sec-type="invalid-section" (valor inválido) |
ERROR | sem espaço/vírgula/pipe — R5 e R6 não disparam |
| C-R3 | sec-type="transcript" sem @id |
ERROR | "transcript" é válido — R2 passa; sem pipe — R6 não dispara |
| C-R4 | artigo research-article sem <sec sec-type="data-availability"> como filho direto de <body> |
ERROR | regra de nível artigo, gerada por XMLSecValidation; não associada a nenhuma <sec> individual |
| C-R5 | sec-type="materials methods" (espaço sem pipe) |
R2 ERROR + R5 WARNING | cascata estrutural: espaço sem pipe faz "materials methods" não constar em valid_sec_types (R2) e ativa has_space_separator=True (R5) simultaneamente |
| C-R6 | sec-type="transcript|intro" (tipo não-combinável com pipe) |
WARNING | "transcript|intro" != "transcript" — R3 não dispara; ambos os parts são válidos — R2 passa; R5 não dispara (tem pipe) |
| C-R7 | sec-type="discussion" sem <p> direto |
WARNING | paragraph_count = len(element.findall("p")) = 0; R1 passa (tem <title>); R2 passa |
Verificação cruzada com o CSV
Todas as 8 entradas esperadas do módulo sec.py (validation) aparecem no CSV
sob o subject sec, com os níveis de severidade corretos:
| Subject | Caso | Nível | Verificação |
|---|---|---|---|
| sec | C-R1 | CRITICAL | PASS — "Add <title> element to <sec> for accessibility" |
| sec | C-R2 | ERROR | PASS — "Replace @sec-type=\"invalid-section\" with a valid value" |
| sec | C-R3 | ERROR | PASS — "Add @id attribute to <sec sec-type=\"transcript\">" |
| sec | C-R4 | ERROR | PASS — "Add <sec sec-type=\"data-availability\"...> to <body> (required for article-type=\"research-article\")" |
| sec | C-R5 cascata | ERROR | PASS — R2 dispara para "materials methods" inválido |
| sec | C-R5 | WARNING | PASS — "Use pipe | as separator in @sec-type=\"materials methods\"" |
| sec | C-R6 | WARNING | PASS — "Do not combine \"transcript\" with other types in @sec-type=\"transcript|intro\"" |
| sec | C-R7 | WARNING | PASS — "Add at least one <p> element to <sec>" |
O caso ouro P1 não gera nenhuma entrada. Não foram identificados falsos positivos nem falsos negativos originados do módulo.
Ruído identificado (outros módulos) — 20 entradas
Ruído estrutural (XML artificial mínimo): abstract ausente, history dates ausentes (received, rev-request, rev-recd, accepted, pub), subj-group heading ausente, disp-formula, inline-formula, table-wrap, fig e app ausentes.
Ruído de ambiente: rendition PDF ausente, DOI não registrado no Crossref, issue não verificada no Core.
Ruído com sobreposição identificada: o módulo open science (subject open science, CRITICAL) disparou para a mesma condição de C-R4. Isso ocorre porque dois módulos distintos verificam a declaração de disponibilidade de dados: sec.py verifica a presença estrutural de <sec sec-type="data-availability"> em <body> (subject sec), enquanto o módulo de open science verifica a declaração como um todo (subject open science). Ambas as entradas são esperadas e corretas; distinguem-se pelo campo subject no CSV.
Conclusão
O módulo sec.py (validation) 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. A cascata C-R5 (R2 ERROR + R5 WARNING para sec-type="materials methods") é estrutural e esperada: o formato incorreto invalida o valor simultaneamente para as duas regras.
O que esse PR faz?
Implementa validações para o elemento
<sec>conforme SPS 1.10, cobrindo 7 de 10 regras (70%):<title>obrigatório@sec-typevalores válidos@idem transcript<sec sec-type="transcript">exige@iddata-availabilityobrigatório<p>Novos arquivos:
packtools/sps/models/sec.py—Sec,ArticleSecspacktools/sps/validation/sec.py—SecValidation,XMLSecValidationpacktools/sps/validation_rules/sec_rules.jsontests/sps/validation/test_sec.py— 29 testesModificados:
xml_validations.py—validate_secs()xml_validator.py— gruposecno pipelineOnde a revisão poderia começar?
packtools/sps/validation/sec.py— contém toda a lógica de validação. O modelo empacktools/sps/models/sec.pyé a dependência principal.Como este poderia ser testado manualmente?
Ou via pipeline completo:
Algum cenário de contexto que queira dar?
Segue os mesmos padrões de
GraphicValidation/XMLGraphicValidation: modelo extrai dados, validação individual por elemento viaSecValidation, eXMLSecValidationorquestra + adiciona validação de nível de documento (presença dedata-availability). Regras P2 (hierarquia de@sec-type,@specific-use, ordem lógica) ficam fora do escopo conforme definido na issue.Screenshots
N/A — validação backend sem componente visual.
Quais são tickets relevantes?
Criar validações para o elemento
<sec>(SPS 1.10).Referências
<sec>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
<sec>conforme a especificação SPS 1.10, aumentando a conformidade de X% para 70% (7 de 10 regras).Nota: Algumas validações para
<sec>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
<sec>representa seções de texto do documento. Para acessibilidade, cada seção deve obrigatoriamente conter<title>. Seções de primeiro nível que correspondem a tipos específicos (métodos, resultados, etc.) devem ter o atributo@sec-type. Alguns tipos de documentos requerem obrigatoriamente seção de disponibilidade de dados (@sec-type="data-availability"). Validações corretas garantem acessibilidade, presença de elementos obrigatórios, e conformidade com requisitos de tipos de documentos.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.sec
Regras principais conforme SPS 1.10:
Ocorrência:
<sec>pode aparecer zero ou mais vezes em:<abstract>,<app>,<back>,<bio>,<body>,<boxed-text>,<sec>,<trans-abstract>Elemento obrigatório (Acessibilidade):
<title>é mandatório em<sec>para criar títulos acessíveisAtributo
@sec-type:Valores permitidos para
@sec-type:cases- Relatos/casos/estudos de casoconclusions- Conclusões/considerações finais/comentáriosdata-availability- Declaração de Disponibilidade de Dadosdiscussion- Discussões/interpretaçõesintro- Introdução/sinopsematerials- Materiaismethods- Metodologias/métodos/procedimentosresults- Resultados/descobertassubjects- Participantes/Pacientessupplementary-material- Material suplementar/material adicionaltranscript- Transcrição de vídeo ou áudioSeções combinadas:
|como separadormaterials|methodssupplementary-material,transcriptedata-availabilitynão podem ser combinados@sec-type="data-availability"obrigatório:data-article,brief-report,case-report,rapid-communication,research-article,review-article@specific-use@sec-type="transcript"exige@id:@idobrigatórioEstrutura:
<title>) seguido de um ou mais parágrafos (<p>)Regras a Implementar
P0 – Críticas (implementar obrigatoriamente)
<title><title>é mandatório em<sec>(requisito de acessibilidade)@sec-type@sec-typedeve ter valor da lista permitida@idemtranscript@sec-type="transcript"deve ter atributo@iddata-availabilityem documentos indexáveis@sec-type="data-availability"P1 – Importantes (implementar se possível)
transcript,supplementary-materialedata-availabilitynão são combinados<p>após<title>P2 – Futuras (fora do escopo deste Issue)
@sec-typesó é usado em seções de primeiro nível@specific-usequando@sec-type="data-availability"Arquivos a Criar/Modificar
Avaliar existentes (podem ter validações parciais...
🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.