feat(regua): a unidade de medida passa a ser a aula, e os numeros vem da fonte unica - #70
Merged
Merged
Conversation
… da fonte única Os cursos gerados saíam rasos: apresentavam o conceito e não o explicavam. A causa era a régua, não o modelo. O gate media MÓDULO com piso de 2.500 palavras e uma bateria de pisos (3+ exercícios, 5+ estatísticas, 3+ fontes, 1+ tabela, 1+ blockquote, 3+ blocos visuais), e o prompt dava cota de palavras por parte. Cota se cumpre com abrangência, não com explicação. A unidade agora é a AULA (tipo D da fonte de estilo escrita-empreendedor, hash a10ed133): piso 900, alvo 1.200-2.400, aviso 2.400, erro 3.600 palavras; 2 a 4 H2; até 2 H3 por H2; até 3 apoios visuais; parágrafo de 15 a 45 palavras; 1 exercício por aula; 1 fonte datada e 1 cápsula por trilha. Nenhum número da régua mora mais neste repositório. config/lexicos.json é espelho gerado da fonte e lexicos_loader.py o lê em runtime; content_checker interpola o valor carregado na mensagem de erro, então código, configuração e mensagem não conseguem divergir. Compatibilidade: check_content(..., unidade="modulo") mede a peça como 4 a 6 aulas (4.800-14.400 palavras), que é o que o pipeline ainda entrega. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Nenhum PR foi fechado, mergeado ou rebaseado: o arquivo é recomendação com evidência por PR (arquivo já em main, tamanho do arquivo em main contra o do branch, ancestralidade do commit). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Os cursos gerados saíam rasos: apresentavam o conceito e não o explicavam. A causa não era o modelo, era a régua. O gate media módulo com piso de 2.500 palavras e uma bateria de pisos, e o prompt dava cota de palavras por parte. Cota se cumpre com abrangência, não com explicação: o redator listava seis conceitos em vez de explicar um.
Este PR aplica a seção
### curso-factorydoPLANO_DE_MIGRACAO.mdda fonte única de estilo (alexandrebrt14-sys/escrita-empreendedor, hasha10ed133921bd8f3f270a9980db43fe41ee05608bc5204b40dfd4b03f6f102b5).Antes e depois
config/lexicos.json, espelho gerado da fonteCompatibilidade. O pipeline ainda entrega "módulo", então
check_content(..., unidade="modulo")mede a peça como 4 a 6 aulas: 4.800-14.400 palavras, piso 3.600, erro 21.600.QualityGate.check_textusaunidade="modulo"por padrão para não reprovar o acervo; quando o gerador emitir aula, o chamador passaunidade="aula". Está documentado no docstring decheck_contente detetos_da_unidade.Um número só por regra.
config/lexicos.jsonsai depython -m escrita.cli lexicos --jsonrodado na fonte e nunca é editado à mão.content_checkerlê os tetos dali e interpola o valor carregado na mensagem de erro, em vez de repetir um literal — código, configuração e mensagem não conseguem mais divergir. As constantesFALLBACK_*só entram se o espelho sumir, para que uma configuração corrompida não desligue o gate em silêncio.Arquivos
config/lexicos.jsonsrc/validators/lexicos_loader.pytetos_da_aula()eexpressoes_vetadas(). Nunca levanta exceçãosrc/validators/content_checker.pytetos_da_unidade()com o modo de compatibilidade; extensão, H2, H3/H2, teto de visuais, 1 exercício; parágrafo em palavras;FORBIDDEN_CLICHESpodado para 13; poda de substring nas expressões vetadassrc/validators/quality_gate.pycheck_text/check_htmlganhamunidade, padrão"modulo", com o motivo no docstringsrc/validators/voice_guard.pycontent_checkerconfig/quality_rules.yamlcontent_qualityreescrito: só o que é específico do repo (aulas por trilha, exercício por aula, fonte por trilha); as 21 expressões que a fonte já cobria saíram; nota de unidade emvisual_densitysrc/templates/prompts/draft.mdept-br/draft.mdsrc/orchestrator.pydocs/GOVERNANCA_PUBLICACAO_CURSO.mdDIRETRIZ_EDITORIAL.mdGUIA_ESCRITA_HUMANIZADA.mddocs/research/HUMANIZACAO_AI_ESTADO_DA_ARTE_2026.mdtests/test_regua_aula.pytests/test_validators_smoke.py,tests/test_voice_guard.pydocs/TRIAGEM_PRS_20260827.mdoutput/.gitignore)Testes
Dois testes existentes precisaram mudar, e os dois por causa da mudança:
test_cliche_usa_fallback_quando_yaml_nao_carregaafirmava que, sem o YAML, "especialistas apontam" deixava de ser checado. Com o espelho da fonte a cobertura não depende mais do YAML do repo, então o teste passou a afirmar o contrário (e foi renomeado).test_anti_cliche_one_offencecaiu de 75 para 50 porque "em um mundo cada vez mais" contém o conectivo "cada vez mais" e o mesmo trecho era cobrado duas vezes. A correção foi no código (poda de substring em_check_cliches), não no teste, e o teste agora documenta a armadilha.Triagem de PRs (nenhum foi tocado)
16 PRs abertos: 5 para mergear (#65, #62, #58, #56, #52), 5 para fechar como superados (#42, #35, #28, #26, #21), 5 para rebase (#61, #36, #34, #27, #1) e 1 para manter (#43). Evidência por PR em
docs/TRIAGEM_PRS_20260827.md.O que ficou de fora
src/templates/page.tsx.j2(blocos fixos por trilha, paginação, barra de progresso por trilha) não entrou: é o motor de renderização e mexer nele junto com a régua misturaria duas mudanças com riscos diferentes.editorial.words_per_module_min/maxemconfig/clients/*/client.yamlcontinua com os números antigos. É configuração morta: carregada porloader.py, nunca consumida. Vale apagar num PR de limpeza.en/draft.mdees/draft.mdseguem com a estrutura antiga. O teste de espelho de idioma cobre sópt-brcontra a raiz, e traduzir a nova estrutura é trabalho editorial próprio.🤖 Generated with Claude Code