Changelog 3.1.0

O que mudou no SpiderHead, release por release. Cada entrada informa o tipo da mudança e se ela funciona hoje.

Releases no GitHub

11 de outubro de 2026

5 adicionado54 alterado2 corrigido
  • AlteradoFuncionaReconstrói Agenda e Rastreamento das configurações do projeto com componentes nativos de#1323

    canvas compartilhados, fontes Roboto offline e Material Symbols, e layout de coluna única em 800 px.

    #1323 (issue no GitHub)
  • AlteradoFuncionaUsa inglês em toda a interface do aplicativo, mantém o comando de agendamento existente e#1323

    os contratos de documento, e exibe apenas dados de agendamento respaldados pelo núcleo.

    #1323 (issue no GitHub)
  • AlteradoFuncionaPreserva identidades e aliases de workspace enquanto as Configurações do projeto estão#1323

    abertas; impede salvamentos duplicados enquanto o núcleo responde.

    #1323 (issue no GitHub)
  • AlteradoFuncionaAs configurações do projeto no desktop ganham uma aba Agenda (dias da semana, dias do#1322

    mês, janela de execução, fuso horário, concorrentes) e uma aba Rastreamento (modo de rastreamento, predefinição ou string personalizada de User-Agent, pausa entre requisições, orçamento de URLs, SpiderHeadBot ou um user agent personalizado); ambas leem e gravam o projeto pelo núcleo, e a visão geral do projeto mostra a próxima e a última execução agendada. Um modo --tray executa os scans vencidos do núcleo e mantém o Mac acordado apenas enquanto um scan roda.

    #1322 (issue no GitHub)
  • AlteradoFuncionaScans agendados de projeto (#1322, núcleo): schedule.json no diretório do projeto#1322

    guarda…

    Scans agendados de projeto (#1322, núcleo): o schedule.json no diretório do projeto guarda a programação (dias da semana e/ou dias do mês, janela de horário no fuso horário do site, ativar ou desativar, concorrentes, modo de rastreamento spider/sitemap/list, orçamentos de URLs e de requisições por execução, intervalo de cortesia entre requisições e modo de fatias, que retoma o rastreamento parcial anterior). Ele é editado por schedule-set / seo_schedule_set com expected_revision, e o schedule-show mostra a última execução e a próxima janela devida. O schedule-run-due é um ponto de entrada sem interface que executa só os scans vencidos, recusa sobreposição com um lease e registra cada decisão no diário do projeto. schedule-install e schedule-uninstall gravam ou removem um plist do launchd, uma linha de cron ou um comando do Agendador de Tarefas somente quando são chamados explicitamente.

    #1322 (issue no GitHub)
  • AlteradoFuncionaUser agents de rastreamento (#1322): predefinições (spiderhead, googlebot,#1322

    googlebot-desktop, googlebot-smartphone, bingbot, yandexbot, yandexmobilebot, baiduspider, duckduckbot, applebot, gptbot, claudebot, perplexitybot, além de navegadores para desktop e mobile) ou uma string personalizada. O padrão agora é SpiderHeadBot/<version> (+https://github.com/PavloSEO/spiderhead), e a correspondência do grupo do robots.txt usa a mesma identidade. Sites que correspondiam ao grupo antigo SEOHEAD-Tools no robots.txt devem citar SpiderHeadBot nas suas regras.

    #1322 (issue no GitHub)
  • AlteradoFuncionaUm rastreamento de projeto salvo agora marca os itens automáticos do checklist que ele#1314

    mediu.

    Cada item ativo do checklist recebe um de três resultados: succeeded, quando a auditoria salva executou a verificação, com o scan como evidência; unavailable, quando o rastreamento pulou ou desativou a verificação, mantendo o motivo informado por ele; ou unmeasured, quando a auditoria não menciona a verificação. Um item não medido mantém o registro anterior e aparece pelo nome em checklist_evidence, então nunca conta como 0. Um rastreamento que falha ou é interrompido marca suas verificações automáticas como failed, com o motivo da falha. O mesmo caminho de registro agora atende o fluxo prepare, que antes tinha uma cópia própria do loop. Um projeto com checklist não inicializado é ignorado, com o motivo informado.

    #1314 (issue no GitHub)
  • AlteradoFuncionaWorkspaces de concorrentes mantêm a URL como foi digitada: o rastreamento começa pela URL#1314

    www…

    Workspaces de concorrentes mantêm a URL como foi digitada: o rastreamento de um concorrente começa pela URL www, em vez do host puro, e o rastreamento de uma URL de concorrente não marca mais os itens do checklist do dono; o resultado é registrado somente no workspace do próprio concorrente. Abrir um projeto com workspace de concorrente danificado informa que esse concorrente está indisponível, em vez de falhar.

    #1314 (issue no GitHub)
  • AlteradoFuncionaCandidatos a concorrente podem ser registrados, listados e removidos pela CLI#1314

    (project-competitors-add, project-competitors-list, project-competitors-remove) e pelas ferramentas MCP seo_project_competitors_* correspondentes. Cada candidato mantém a URL como foi digitada, incluindo um host www, e hosts com e sem www contam como o mesmo site nas verificações de duplicidade. Um concorrente com host www não quebra mais a preparação nem faz o project-observe falhar.

    #1314 (issue no GitHub)
  • AlteradoFunciona--max-urls agora é o orçamento de páginas do rastreamento: um orçamento explícito#1314

    preenche os de requisições…

    --max-urls agora é o orçamento de páginas do rastreamento: um orçamento explícito preenche os orçamentos de requisições e de tempo que não foram definidos (3 requisições e 2 segundos por página), então rastreamentos de 50–300 páginas são aceitos sem approve_large_crawl; orçamentos acima dos limites do projeto continuam sendo recusados.

    #1314 (issue no GitHub)
  • AlteradoFuncionaUma parada deliberada por orçamento de URLs é salva como captura concluída, com#1314

    finish_reason stopped_by_budget e um horário finished_at, em vez de interrupted sem horário de término. As URLs que ficaram na fila permanecem para uma retomada.

    #1314 (issue no GitHub)
  • AlteradoFuncionaURLs de concorrentes mantêm o host como foi digitado (por exemplo, www. continua), em#1314

    vez de serem armazenadas sem ele.

    #1314 (issue no GitHub)
  • AlteradoFuncionaO Desktop adiciona sites concorrentes pela área de transferência ou um a um pelo núcleo,#1314

    define um limite de URLs por site e inicia os scans deles em paralelo; um concorrente só aparece como escaneado depois de um scan retido e concluído.

    #1314 (issue no GitHub)
  • AlteradoFuncionaScans nativos medem HSTS, conteúdo misto e dados estruturados a partir das evidências#1314

    armazenadas…

    Scans nativos medem HSTS, conteúdo misto e dados estruturados a partir das próprias evidências armazenadas, então uma exportação do SF ausente ou desatualizada não os aponta mais como ausentes. O duplicate-check marca como não medida uma execução com zero pares comparados. Problemas de template em todo o site (mesmo bloco de layout no cabeçalho, baixa proporção de texto) viram um único problema com a contagem de páginas (#1314).

    #1314 (issue no GitHub)
  • AlteradoFuncionaAceitar uma meta do dono adiciona apenas a tarefa de checklist dessa meta.#1314

    Isso não reconcilia mais todo o catálogo interno com coverage.json; as linhas internas são adicionadas sob demanda, quando uma delas é tocada.

    #1314 (issue no GitHub)
  • AlteradoFuncionaUm checklist ocupado identifica o detentor ativo (por exemplo, um rastreamento nativo em#1314

    execução e o seu pid), em vez de chamar o lock de resíduo. O lock registra o pid de quem escreve; um lock sem detentor ativo continua sendo reportado como resíduo.

    #1314 (issue no GitHub)
  • AlteradoFuncionaUma execução de workflow bloqueada por uma etapa com falha, indisponível, ignorada ou#1314

    interrompida continua retomável, e uma etapa pendente posterior pode receber checkpoint mesmo após uma etapa sem sucesso. As etapas ainda precisam receber checkpoint na ordem registrada, e uma execução interrompida continua recusando novas etapas.

    #1314 (issue no GitHub)
  • AlteradoFuncionaUma revisão registrada por agente deixa de tornar um item manual ou entregável completo#1314

    pelo dono.

    O item continua aguardando a aprovação do dono ou de um revisor que não seja agente.

    #1314 (issue no GitHub)
  • AlteradoFuncionaReferências da caixa de entrada aceitam ids de metas (inbox:<uuid>), para que uma nota#1314

    cite a meta a que se refere…

    Referências da caixa de entrada aceitam ids de metas (inbox:<uuid>), para que uma nota possa citar a meta a que se refere.

    #1314 (issue no GitHub)
  • AlteradoFuncionaItens do checklist nunca tentados e manuais passam a mostrar o estado not_run, em vez#1314

    de review; apenas uma tentativa aguardando decisão permanece em review.

    #1314 (issue no GitHub)
  • AlteradoFuncionaO modelo de leitura de Issues (evidências de problemas do observe) informa contagens#1314

    por verificação (by_check) e um next_offset após os primeiros 20 problemas; findings_page pagina pelo restante.

    #1314 (issue no GitHub)
  • AlteradoFuncionaVerificações nativas de rastreamento (#1314): o tamanho de imagem (IMG_OVER_KB) agora é#1314

    medido a partir das próprias requisições de imagem do rastreamento, e o status do sitemap (SITEMAP_URL_4XX_5XX, SITEMAP_URL_3XX, SITEMAP_URL_NON_INDEXABLE) a partir da busca feita pelo próprio rastreamento em cada URL listada no sitemap. Uma URL listada que o rastreamento nunca requisitou é contada como não medida, nunca como limpa. IMG_MISSING_ALT, IMG_MISSING_DIMENSIONS e HREFLANG_ERROR informam, em um scan nativo, que o rastreamento não os mede da forma como a exportação do SF define, em vez de apontar para um filtro do SF. Hreflang ausente e evidência de conteúdo misto em um scan nativo são reportados como não medidos pelo rastreamento nativo, e não como exportação ausente.

    #1314 (issue no GitHub)
  • AlteradoFuncionaDiário do projeto (#1314): cada evento do projeto agora também é gravado como um item em#1314

    log.md, e o núcleo registra entradas automáticas para rastreamentos concluídos (scans), relatórios de projeto gerados e tentativas de checklist (agent). As entradas vão para events.jsonl e são lidas por project-event-page; os ganchos automáticos nunca fazem falhar o rastreamento, o relatório ou a etapa de checklist que descrevem. project-event-append e seo_project_event_append mantêm sua interface e ganham a linha em log.md.

    #1314 (issue no GitHub)
  • AlteradoFuncionaO rastreamento nativo agora armazena os cabeçalhos de segurança que as verificações leem#1314

    (Strict-Transport-Security, Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy). Antes, eles eram descartados na captura, então um site que enviava HSTS era apontado como sem HSTS. Os cabeçalhos Set-Cookie guardam apenas suas flags (secure, httponly, samesite=), nunca o nome ou o valor do cookie. Um cabeçalho de segurança enviado mais de uma vez na mesma página é reportado como DUPLICATE_SECURITY_HEADER.

    #1314 (issue no GitHub)
  • AlteradoFuncionaworkflow-start precisa só de uma meta aceita pelo dono: --goal-id (ou#1314

    context.goal_id)…

    workflow-start precisa apenas de uma meta aceita pelo dono: --goal-id (ou context.goal_id) basta. O prompt registrado usa por padrão skill:workflow/full-audit-v1, e a tarefa de checklist usa por padrão a que aceitou a meta criada (custom:goal-<entry>). As recusas informam o comando do dono que corrige o vínculo que falta. As opções estão documentadas em seohead workflow-start --help.

    #1314 (issue no GitHub)
  • AlteradoFuncionaPopulações de checklist aceitam objetos parciais: apenas kind e source são#1314

    obrigatórios, e as demais chaves ficam sem valor por padrão. Uma população recusada informa as chaves ausentes ou desconhecidas.

    #1314 (issue no GitHub)
  • AlteradoFuncionaRastreamentos nativos de projeto usam o /sitemap.xml da origem como alternativa quando#1314

    o robots.txt não declara nenhum sitemap. Quando essa alternativa não existe, ela é registrada como incompleta, mas não interrompe o rastreamento.

    #1314 (issue no GitHub)
  • AlteradoFuncionaLogs de servidor agora guardam totais exatos de IPs de bots em disco, em vez de uma#1311

    amostra limitada, com registros por IP limitados, visitas, última visita e filtros por sub-rede. A verificação explícita de DNS checa separadamente cada IP selecionado, registra evidências de PTR e de resolução direta, suporta IPv6 e preserva os resultados de indisponível ou prazo esgotado como não verificados. Caches locais expiram após uma hora; leituras nunca disparam consultas DNS.

    #1311 (issue no GitHub)
  • AdicionadoFuncionaAdicionados: importação local de logs do projeto, resumo paginado, evidências de bots e#1311

    junção com scans nativos…

    Adicionados: importação local de logs do projeto, resumo paginado, evidências de bots e comandos de junção com scans nativos, pelos handlers compartilhados da CLI e do MCP. Os artefatos de log separados mantêm partições por data e a cobertura e a proveniência das fontes, sem alterar os esquemas congelados dos scans. Evidência ausente ou incompleta retém conclusões de ausência. As telas de logs do Desktop continuam como um acompanhamento de apresentação separado.

    #1311 (issue no GitHub)
  • AlteradoFuncionaControla as chamadas de produção ao Google DataForSEO antes da criação do cliente, expõe#1310

    cotações offline a partir dos preços de provedor fornecidos, considera a profundidade de SERP e as cobranças por operador de busca, e aplica tetos conhecidos em USD por chamada antes do transporte. Expande operações limitadas de índice de backlinks e registra no diário os custos ausentes ou formatos de resposta malformados como recibos incertos. Os limites de moeda por projeto e por mês continuam pendentes de uma decisão do dono.

    #1310 (issue no GitHub)
  • AlteradoFuncionaMescla evidências explícitas de origem e importação de backlinks em snapshots locais#1310

    privados de histórico, com observações completas de tokens de rel, âncoras, domínios de referência, filtros e sinais transparentes de revisão de spam. Adiciona rotas CLI/MCP de perfil e de exportação revisada de disavow, sem envios automáticos.

    #1310 (issue no GitHub)
  • AdicionadoFuncionaAdiciona avisos de revisão de tokens rel mistos e de divulgação de patrocínio em links de#1310

    saída, a partir de evidências nativas retidas, preservando o contexto indisponível, contagens nulas para populações HTML totalmente não analisadas e as classes sponsored, ugc e nofollow nos relatórios e nas verificações de doadores, sem alterar o esquema congelado dos scans retidos.

    #1310 (issue no GitHub)
  • AlteradoFuncionaVerificações nativas de DOM e de duplicidade agora leem o documento retido selecionado de#1307

    cada página pela URL exata, com linhagem verificada de resposta e corpo. Desativação de retenção, corpos ausentes, inválidos ou acima do orçamento continuam como omissões explícitas; problemas parciais carregam cobertura. Hashes exatos da área de conteúdo e problemas SimHash/LSH limitados persistem na auditoria nativa sem exigir um diretório HTML do SF. As faixas LSH adaptadas ao limiar preservam o recall de pares qualificados e reduzem os buckets de candidatos amplos; o esgotamento do orçamento da análise de quase-duplicatas não descarta os problemas de hash exato.

    #1307 (issue no GitHub)
  • AlteradoFuncionaAuditorias do SF executam opcionalmente similaridade semântica e revisão de title/H1#1307

    versus corpo retido, com um adaptador local fornecido explicitamente ou embeddings declarados. Nenhum modelo ou provedor é escolhido automaticamente. Identidade do adaptador, hashes de origem, scores, limites e omissões acompanham os candidatos à revisão; similaridade semântica não afirma conteúdo duplicado, relevância para a consulta nem canibalização. As duas linhas de cobertura semântica do SF continuam como lacunas até que um adaptador real seja escolhido e validado. A autorização de provedor externo exige o booleano literal true; valores que apenas parecem verdadeiros, como strings ou inteiros, nunca autorizam uma chamada de embedding.

    #1307 (issue no GitHub)
  • AlteradoFuncionaAuditorias nativas retidas agora agrupam links internos quebrados por destino observado,#1306

    com evidências de origem e âncora; registram cadeias e loops de redirecionamento com o status de cada salto; diferenciam busca interna baseada em caminho e âncoras vazias; e expõem resultados capturados de links externos sem resposta. Problemas de consistência de sitemap e robots usam pertencimento e evidências de resposta retidos, sem novas buscas ao vivo; evidências ausentes ou parciais continuam explícitas.

    #1306 (issue no GitHub)
  • AdicionadoFuncionaAdicionado um grafo de links limitado de scans salvos, com filtros de#1306

    posição/seção/vizinhança local…

    Adicionado um grafo de links limitado de scans salvos, com filtros de posição, seção e vizinhança local, agregação por seção e mudanças de arestas entre scans. A reanálise offline preenche as posições com lotes derivados retomáveis e informa evidências não classificadas na inspeção de links e no status do scan, preservando o esquema congelado scan.v1.

    #1306 (issue no GitHub)
  • AdicionadoFuncionaAdicionada geração local de sitemap XML a partir de páginas 200 canônicas e indexáveis#1306

    retidas, com lastmod observado, exclusões, divisão conforme o limite do protocolo, índice de sitemap e sitemap de imagens opcional. CLI e MCP usam as mesmas implementações; a publicação da saída exige um diretório local novo e nunca faz deploy de arquivos.

    #1306 (issue no GitHub)
  • AlteradoFuncionaPreserva alvos de descoberta ausentes no momento da captura quando um processamento#1306

    posterior de sitemap ou seeds…

    Preserva alvos de descoberta ausentes no momento da captura quando um processamento posterior de sitemap ou de seeds adiciona a URL ao catálogo retido. Evidências explicadas de não resolvido ou excluído permanecem imutáveis, enquanto alvos conhecidos declarados e divergências de identidade não nulas continuam inválidos.

    #1306 (issue no GitHub)
  • AlteradoFuncionaA geração de sitemap de imagens exclui respostas de recursos conhecidas diferentes de#1306

    200, mesmo quando o recurso não foi armazenado como página rastreada, e marca respostas de imagem não medidas como cobertura parcial.

    #1306 (issue no GitHub)
  • AlteradoFuncionaRetém atributos brutos de canonical e paginação como contexto versionado do documento,#1305

    sem alterar o SQL congelado do scan. Links canonical com atributos hreflang, lang, media ou type não suportados, anotações malformadas e declarações entre hosts ou protocolos diferentes agora geram problemas com evidência vinculada; palavras-chave de relação bem formadas e desconhecidas continuam não classificadas.

    #1305 (issue no GitHub)
  • AlteradoFuncionaEstende sondagens limitadas de alvos no mesmo host para a paginação e retém observações#1305

    medidas de noindex/canonical…

    Estende sondagens limitadas de alvos no mesmo host para a paginação e retém observações medidas de noindex e canonical. Cadeias canonical nativas e problemas de noindex em canonical/hreflang podem usar as sondagens; sondagens antigas, só de status, continuam legíveis e não medidas para diretivas HTML.

    #1305 (issue no GitHub)
  • AlteradoFuncionaJulga cadeias de paginação nativas opacas quanto a contradições explícitas e recíprocas#1305

    de next/prev, mantendo as regras numeradas e de passo e os estados nomeados como não julgados. Seleciona as URLs dos problemas salvos, inclusive dos membros agrupados, por meio de scan-url-query, usando tabelas temporárias do SQLite e evidências audit.v2 em streaming.

    #1305 (issue no GitHub)
  • CorrigidoFuncionaMantém tokens de relação Unicode desconhecidos e com pontuação como não classificados,#1305

    normaliza autoridades canonical equivalentes com IDN ou porta padrão e preserva os caminhos-alvo exatos da paginação nativa. Tokens de página mistos ilegíveis continuam não julgados; o defeito de paginação da loja é reconhecido mesmo quando a página um não tem número na URL.

    #1305 (issue no GitHub)
  • AlteradoFuncionaRenderiza as anotações next/prev declaradas no fixture da loja, para que sua verdade de#1305

    referência D41 de paginação seja realmente servida e possa ser validada pela captura nativa.

    #1305 (issue no GitHub)
  • AlteradoFuncionaRetém evidências estáticas de AMP e de acessibilidade vinculadas ao documento nas linhas#1304

    de contexto de scan existentes, preservando o esquema SQL congelado scan.v1. Problemas estruturais de AMP inspecionam a declaração doctype original, head e body, charset UTF-8, viewport, script de runtime e declarações de boilerplate; alvos AMP pareados sem marcador de raiz AMP são identificados à parte. As regras completas do validador AMP continuam indisponíveis até que haja uma decisão de licença.

    #1304 (issue no GitHub)
  • AlteradoFuncionaInicia problemas de acessibilidade sobre idioma do documento, rótulos de formulário,#1304

    textos alternativos de imagem, saltos de título e o landmark main. Os problemas preservam exemplos limitados e contagens completas de ocorrências. Contraste calculado e regras de axe-core renderizadas continuam não medidas.

    #1304 (issue no GitHub)
  • AlteradoFuncionaValida Microdata do Schema.org e sujeitos e propriedades comuns de RDFa com o vocabulário#1304

    incluído e as regras existentes de resultados avançados. Erros, avisos e propriedades obrigatórias ausentes retidos por URL viram problemas nativos. Construções RDFa não suportadas são evidência parcial explícita, não um resultado de validação limpo.

    #1304 (issue no GitHub)
  • AlteradoFuncionaServe árvores JSON-LD analisadas junto com erros por bloco de origem, posição e sintaxe#1304

    em scan-structured-blocks; limita árvores de propriedades muito largas e expõe esse limite. Lê o documento mais recente de uma URL e de uma representação solicitadas, sem alterar o seu scan.

    #1304 (issue no GitHub)
  • AlteradoFuncionaPreserva evidência estruturada parcial ou indisponível sem ocultar erros irmãos#1304

    confirmados.

    Resolve identidades JSON-LD suportadas contra a mesma base de documento da marcação HTML, preservando o JSON de origem; rejeita blocos JSON escalares ou vazios como grafos válidos e compartilha a seleção normalizada de tags JSON-LD ao vivo entre o parser e as projeções servidas.

    #1304 (issue no GitHub)
  • AlteradoFuncionaAuditorias nativas agora expõem marcação no head que bloqueia a renderização, a partir de#1303

    HTML retido completo, sem…

    Auditorias nativas agora expõem marcação no head que bloqueia a renderização, a partir do HTML retido completo, sem alterar o esquema congelado scan.v1. Corpos ausentes, incompletos ou limitados pelo orçamento continuam indisponíveis. A detecção existente de recursos do head e a entrada de extração personalizada do SF são reaproveitadas.

    #1303 (issue no GitHub)
  • AdicionadoFuncionaAdiciona orçamentos configuráveis de navegação observada e de bytes por recurso#1303

    individual…

    Adiciona orçamentos configuráveis de navegação observada nativa e de bytes por recurso individual, sinais de entrega de cache e fontes, heurísticas de minificação e de scripts legados, e duplicatas exatas de script na mesma página, a partir das evidências retidas do scan.v2. Dados não buscados e cargas de runtime incompletas continuam explícitos; declarações responsivas não são somadas como peso de runtime. Limites inferiores apenas com HTML, contagens escalares de cobertura, amostras de fontes e resumos de origem continuam explícitos e limitados.

    #1303 (issue no GitHub)
  • AlteradoFuncionaColeta cobertura precisa limitada de JS/CSS do Chromium em renders solicitados, retém#1303

    resumos de uso em UTF-16 e problemas de dimensionamento de imagem renderizada, e os lê após reabrir ou na reanálise offline. Motores não suportados e medições ausentes não viram resultados limpos.

    #1303 (issue no GitHub)
  • AlteradoFuncionaAceita JSON do Lighthouse por URL, limitado e correspondente, para descoberta de LCP,#1303

    árvores de dependência, responsáveis por layout shift, entrega de imagens, reflow forçado e problemas de execução de script, com proveniência de captura e hashes das entradas. Nenhum processo do Lighthouse, provedor pago ou inferência de CWV de campo é adicionado. Atualiza o registro, a cobertura do SF e a documentação de referência gerada.

    #1303 (issue no GitHub)
  • CorrigidoFuncionaMantém os limiares de recursos adicionais fora do cabeçalho congelado do scan nativo e#1303

    armazena seus valores exatos em um contexto de execução validado e versionado. A retomada compara esses valores separadamente, e a reanálise offline os restaura a partir das evidências retidas; leitores leves mais antigos ainda podem inspecionar o formato inalterado da configuração do cabeçalho.

    #1303 (issue no GitHub)
  • AlteradoFuncionaO record do checklist agora aceita uma verificação automática com sucesso cujo scan

    salvo é um scan audit.v2 em streaming; antes falhava com 'NoneType' object is not subscriptable, porque a auditoria fica no companion, e não na tabela legada do scan. Os formatos de registro aceitos estão documentados em seohead project checklist-record --help, no esquema MCP de seo_project_checklist_record e em docs/INPUTS.md.

  • AlteradoFuncionaExecuta a suíte completa do toolkit uma vez no Python 3.15, em vez de uma matriz de

    versões antigas, mantendo quatro grupos de testes verificados e cobertura combinada. Use a mesma versão estável do Python nos bootstraps de CI e de build de release.

  • AlteradoFuncionaA lista Work do Desktop lê todas as páginas do checklist (100 por requisição) em vez das

    primeiras 50 linhas; Issues mostra o nome de cada verificação principal do registro, em vez de “Other check”.

  • AlteradoFuncionaO Work do Desktop lê todas as páginas do checklist, mas mostra o painel de tarefas do

    projeto uma página por vez, então um checklist de qualquer tamanho não falha mais com “at most 100 rows”. O Desktop abre o scan que uma auditoria completa deixa para trás (o maior scan completo) quando o dono não escolheu um, e a descoberta do core também verifica o próprio ambiente do interpretador do Desktop (sys.prefix) antes do PATH.

  • AlteradoFuncionaConsolida verificações de auditoria retidas e melhorias nativas do desktop.

    Preserva as configurações de orçamento de recursos sem alterar o cabeçalho congelado do scan, mantém a reanálise offline e a retomada seguras, e compartilha componentes nativos de configurações do projeto, tokens de tema e fontes incluídas. Remove insumos de design privados da árvore distribuída.

  • AlteradoFuncionaVincula as reverificações de remediação à política de assets efetiva validada,

    preservando o cabeçalho original do scan e os bytes de origem.

  • AlteradoFuncionaA cobertura do checklist do projeto agora vincula relatórios audit.v2 em streaming:

    report-build --project e audit-workflow --action report anexam o snapshot do checklist às saídas xlsx, docx, csv, md e PDF de visão geral, em vez de gerar um relatório não vinculado. Um scan interrompido pelo orçamento de URLs (stopped_by_budget) é aceito como o último scan auditado do projeto, e o relatório informa o escopo limitado. report-build --input aceita a chave format. report-build --project --format json em uma auditoria em streaming é recusado com uma explicação, porque o JSON é gravado tal como está e não pode carregar o snapshot do checklist.

10 de outubro de 2026

16 adicionado51 alterado
  • AlteradoFuncionaO monitor de scan do Desktop segue o painel de design ScanRun: porcentagem real a partir#1203

    dos contadores fetched/found, barra de progresso de 10 px, limite de taxa do coletor e um placeholder honesto de gráfico de velocidade de 120 px (o histórico de taxa do core é rastreado em #1203).

    #1203 (issue no GitHub)
  • AlteradoFuncionacheck_sample em seohead/checks/custom_extract.py executa extratores CSS, XPath e#1059

    regex sobre um único documento HTML salvo, sem scan nem requisição de rede. Cada resultado traz seus valores e um reason para um resultado vazio (no_match, empty_html ou budget_exceeded), para que uma resposta vazia nunca seja apresentada como resultado limpo (#1059). É apenas uma chamada do core; ainda não há ferramenta de CLI nem MCP registrada, e buscar uma URL ao vivo foi deliberadamente deixado de fora.

    #1059 (issue no GitHub)
  • AlteradoFuncionaA verificação de sequência de paginação (PAGINATION_SEQUENCE_ERROR) agora julga séries#1057

    com passo: quando um passo cobre a maioria dos passos de uma série, uma quebra desse passo é reportada (?page=1,3,5,8 quebra em 5 para 8). Esquemas de offset irregulares e séries sem numeração continuam sem julgamento e são citados como ignorados.

    #1057 (issue no GitHub)
  • AdicionadoFuncionaNova verificação INTERNAL_NOFOLLOW_OUTLINKS (aviso): lista cada página de origem que…#1052

    Nova verificação de rastreamento INTERNAL_NOFOLLOW_OUTLINKS (aviso): lista cada página de origem que tem links de saída internos com nofollow, com a contagem e uma amostra limitada de destinos. Fecha a lacuna em nível de página da linha “Internal Nofollow Outlinks” do Screaming Frog, que estava como partial. Roda nos rastreamentos nativos e é ignorada pelo nome em execuções só de exportação e de lista de URLs.

    #1052 (issue no GitHub)
  • AlteradoFuncionaO parser lê declarações <link rel="alternate"> com mídia e sem hreflang (uma URL#1051

    móvel separada) e as grava em parse_html como mobile_alternates (#1051). A verificação Mobile Alternate Link do SF ainda é uma lacuna; a que compara o canonical da URL móvel ainda não foi escrita.

    #1051 (issue no GitHub)
  • AdicionadoFuncionaAdiciona a verificação HREFLANG_UNLINKED_TARGET (aviso): um destino alternate de#1050

    hreflang que nenhum…

    Adiciona a verificação HREFLANG_UNLINKED_TARGET (aviso): é reportado qualquer destino alternate de hreflang que nenhum link comum do rastreamento aponta. Assim, o “Unlinked Hreflang URLs” do Screaming Frog passa a ser coberto. A verificação lê o export All Hreflang e a coluna Internal:All Inlinks, do mesmo jeito que UNLINKED_CANONICAL; uma autorreferência não conta, e um rastreamento parcial retém o achado. O registro passa de 182 para 183 verificações.

    #1050 (issue no GitHub)
  • AlteradoFuncionaDimensionamento de imagens em rotas renderizadas: o render-check agora registra o tamanho#1049

    intrínseco em pixels de cada imagem em relação à caixa renderizada e à razão de pixel do dispositivo (image_sizing: evidências de imagens superdimensionadas e ampliadas). É só evidência; ainda não há id de verificação no SF-analyzer, então “Incorrectly Sized Images” passa de gap para partial (#1049).

    #1049 (issue no GitHub)
  • AlteradoFuncionaSemantically Similar: o status continua gap, e a nota agora declara o bloqueio.#1041

    O comando e a ferramenta MCP de similaridade semântica existem, mas nenhum adaptador de embeddings é distribuído e a execução do SF ainda não chama o módulo (#1041).

    #1041 (issue no GitHub)
  • AdicionadoFuncionaAdiciona a verificação INTERNAL_LINK_SPONSORED_UGC (aviso): um link do mesmo site que#1040

    traz…

    Adiciona a verificação INTERNAL_LINK_SPONSORED_UGC (aviso): um link do mesmo site com rel="sponsored" ou rel="ugc" é reportado com o conjunto completo de tokens de rel. Ele precisa de link_attributes.capture, como as demais verificações de link baseadas em rel, e, sem isso, é reportado como não medido.

    #1040 (issue no GitHub)
  • AdicionadoFuncionaAdiciona o núcleo da geração de sitemap XML a partir de um scan retido:#1039

    select_indexable mantém só páginas HTML 200 autocanônicas, sem noindex e não bloqueadas pelo robots, e informa o motivo de cada URL excluída; render_sitemaps grava um <urlset> ou arquivos divididos mais um <sitemapindex> a cada 50.000 URLs ou 52.428.800 bytes por arquivo. A exposição via CLI e MCP vem depois.

    #1039 (issue no GitHub)
  • AdicionadoFuncionaAdiciona cloudflare-traffic (CLI) e seo_cloudflare_traffic (MCP): uma fonte somente#1026

    leitura do GraphQL Analytics da Cloudflare para o analisador de logs, quando os logs da origem não existem (#1026, #1009). Retorna bots × URLs × códigos de status × status de cache por dia, no formato de log-analyze, marcada como source: cloudflare-aggregated porque são dados agregados de borda, não logs brutos (sem IPs de clientes, então sem verificação por reverse DNS). Dias que atingem o limite de 10.000 linhas por página são divididos por janela de tempo; a chamada é contada no livro de gastos como provedor gratuito. O token vem de CLOUDFLARE_API_TOKEN ou SEOHEAD_CLOUDFLARE_TOKEN_FILE e nunca é exibido.

    #1026 (issue no GitHub)
  • AlteradoFuncionaAvaliador interno de achados do Search Console, ainda não ligado aos relatórios:#1025

    seohead/checks/search_console_findings.py cruza as páginas do rastreamento com um documento normalizado de evidências do GSC e avalia GSC_ORPHAN, NO_SEARCH_DATA e NON_INDEXABLE_WITH_SEARCH_DATA. Uma verificação é ignorada, com o motivo, quando o rastreamento é parcial, a janela está incompleta, a coleta é amostrada ou truncada, ou nenhuma evidência é fornecida; uma verificação ignorada nunca é reportada como limpa.

    #1025 (issue no GitHub)
  • AlteradoFuncionacrawl-enrich reporta quatro achados de web analytics a partir de um CSV offline#1024

    indexado por URL: URLs órfãs no analytics, páginas indexáveis sem dados de analytics, páginas não indexáveis com visitas e taxa de rejeição acima de 70%. As colunas nomeadas --visits-column e --bounce-column selecionam os dados; uma coluna ausente é recusada pelo nome, valores ilegíveis são contados e nunca lidos como zero, e URLs órfãs do analytics são retidas em rastreamento parcial. A coleta ao vivo de Metrika/GA4 por URL ainda não está incluída (#990, #984).

    #1024 (issue no GitHub)
  • AlteradoFuncionaO mapa de cobertura de problemas do SF lista os quatro problemas de web analytics (Orphan#1024

    URLs, Bounce Rate Above 70%, No GA Data, Non-Indexable with GA Data) como encontrados pelo crawl-enrich a partir de um CSV offline, em vez de fora do escopo. O sf run ainda não os emite.

    #1024 (issue no GitHub)
  • AlteradoFuncionaNúcleo de cobertura de laboratório para CSS e JavaScript não usados (#1023, fatia 1): um#1023

    analisador puro recebe payloads de page.coverage do Playwright e reporta, por recurso, os caracteres não usados, com um achado quando o recurso é majoritariamente não usado e grande. A coleta de cobertura a partir de uma página renderizada é a próxima fatia.

    #1023 (issue no GitHub)
  • AlteradoFuncionaVerificações de par AMP (#1020): AMP_NON_200, AMP_MISSING_CANONICAL,#1020

    AMP_MISSING_RETURN_LINK, AMP_NON_INDEXABLE_CANONICAL e AMP_INDEXABLE leem o alvo AMP que uma página desktop declara com <link rel="amphtml">. Só são avaliadas as páginas AMP que o rastreamento capturou; um alvo não capturado é ignorado e informado pelo nome. O rastreamento nativo agora registra o alvo resolvido na coluna AMP HTML. As outras dez regras AMP do SF continuam recusadas.

    #1020 (issue no GitHub)
  • AdicionadoFuncionaAdiciona HTML_OVER_2MB, um teto absoluto de 2 MB para um documento HTML, separado de…#1019

    Adiciona HTML_OVER_2MB, um teto absoluto de 2 MB para um documento HTML, separado do LARGE_HTML, que é relativo à mediana. A regra “HTML Document Over 2MB” do Screaming Frog agora aponta para ele, em vez da regra de 200 KB.

    #1019 (issue no GitHub)
  • AdicionadoFuncionaAdiciona o aviso URL_HAS_PARAMETERS à auditoria de rastreamento: uma página HTML#1018

    interna cuja URL tem parâmetros de query é reportada independentemente do estado do canonical. URL_HAS_PARAMS mantém o significado mais restrito, de ausência de canonical (#1018).

    #1018 (issue no GitHub)
  • AlteradoFuncionaDiretivas de robôs (#1017): noodp e noydir legados em meta robots ou X-Robots-Tag#1017

    agora geram os avisos NOODP e NOYDIR na auditoria do SF; antes eram listados como fora do escopo. none (noindex+nofollow) é coberta por testes de regressão tanto no caminho do X-Robots-Tag quanto no da meta tag.

    #1017 (issue no GitHub)
  • AdicionadoFuncionaNova verificação JS_CONSOLE_ERRORS (SF “Pages with JavaScript Errors”): uma página cujo#1015

    console da renderização retida registrou erros. Lida offline a partir dos sidecars de console salvos de um scan nativo, sem nova renderização; um registro que não pode ser lido vira um skip declarado, não uma página limpa. Requer rendering.artifacts.console_errors.

    #1015 (issue no GitHub)
  • AlteradoFuncionaOs rastreamentos agora reportam quatro cabeçalhos de segurança ausentes por página HTML a#1013

    partir da…

    Os rastreamentos agora reportam quatro cabeçalhos de segurança ausentes por página HTML, a partir da resposta final armazenada: MISSING_CSP, MISSING_X_CONTENT_TYPE_OPTIONS, MISSING_X_FRAME_OPTIONS (satisfeita por uma diretiva frame-ancestors do CSP) e MISSING_REFERRER_POLICY. Páginas cujos cabeçalhos armazenados não podem ser interpretados são contadas como não medidas, e não como limpas; um rastreamento sem scan armazenado ignora essas páginas e informa o motivo.

    #1013 (issue no GitHub)
  • AdicionadoFuncionaAdiciona um validador para especificações fechadas de ação de página (click, scroll,#1011

    wait_for_selector, wait_ms) com um orçamento de tempo estático para rastreamentos renderizados. Ele ainda não está ligado à renderização, então o comportamento do rastreamento não muda (#1011).

    #1011 (issue no GitHub)
  • AlteradoFuncionalog-analyze lê logs de acesso comprimidos em gzip (arquivos rotacionados#1009

    access.log.N.gz e arquivos renomeados) diretamente, detectando o formato pelo conteúdo, e não pela extensão. Um arquivo truncado ou corrompido é reportado como erro, sem contagens parciais.

    #1009 (issue no GitHub)
  • AlteradoFuncionascan-url-query ganha predefinições de visualização prontas (--preset, por exemplo#1007

    status_4xx, title_missing, title_over_60, h1_missing, noindex_meta) que se combinam por E com os filtros do usuário, e --export PATH com --export-format csv|xlsx grava todas as linhas correspondentes em um arquivo novo. A exportação é recusada acima de --export-max-rows (padrão 100.000) e nunca sobrescreve.

    #1007 (issue no GitHub)
  • AlteradoFuncionaAs regras de elegibilidade de resultados enriquecidos saíram do código Python e foram#1001

    para seohead/data/rich_results_rules.json, um arquivo de dados versionado, empacotado com o pacote. O campo version desse arquivo é o valor gravado como rules_version em cada veredito de resultado enriquecido; assim, mudar uma regra significa mudar dados, não código.

    #1001 (issue no GitHub)
  • AlteradoFuncionaOs vereditos de resultados enriquecidos (check_schema e as verificações de evidências#1001

    estruturadas armazenadas) agora trazem rules_version, para que cada resultado informe qual conjunto de regras offline o produziu.

    #1001 (issue no GitHub)
  • AlteradoFuncionaDocumenta os seis scripts de manutenção e geração que não tinham referência na#997

    documentação (scripts/generate_project_catalogue.py, generate_registry_inventory.py, render_readme_visuals.py, linux_lifecycle_smoke.py, capacity_watchdog.py, profile_million_audit.py) em docs/README.md, com o que cada um grava e quais rodam no CI (#997).

    #997 (issue no GitHub)
  • AdicionadoFuncionaAdiciona o pipeline de núcleo semântico como seohead/semantics, com banco SQLite#995

    próprio por projeto: seohead semantics <stage> --project DIR (init, import, collect, clean, graph, exact, cluster, competitors, synonyms, report, excel, mine, sitematch, relevance, status, export), as ferramentas MCP seo_semantics_status, seo_semantics_run, seo_semantics_mine e seo_semantics_paid (as etapas pagas exigem confirm_paid=true), clusterização Louvain atrás do novo extra semantics, a skill empacotada semantic-core e um projeto de exemplo sintético. As cobranças de provedor de uma etapa semântica são marcadas no diário de gastos compartilhado (#995).

    #995 (issue no GitHub)
  • AlteradoFuncionaRemove o adaptador guiado do bot do Telegram seohead/integrations/bot; recibos de#995

    entrega do monitor…

    Remove o adaptador guiado do bot do Telegram seohead/integrations/bot; os recibos de entrega do monitor agora ficam em seohead/projects/service_delivery.py (#995).

    #995 (issue no GitHub)
  • AlteradoFuncionascan-url-query retorna click_depth, o menor caminho de links internos a partir da#992

    página inicial do scan, como coluna, filtro e chave de ordenação. Páginas que nenhum link armazenado alcança ficam como NULL (órfãs). crawl_depth não muda e continua sendo a profundidade da fronteira, que é 0 para toda URL vinda de sitemap. Um scan que não reteve seus links falha com reason_code: click_depth_unavailable, em vez de reportar um NULL falso. O valor é recalculado a cada consulta a partir da tabela links; gravá-lo como coluna indexada ao final do scan ainda está em aberto, porque exige uma decisão sobre a versão do schema (#992).

    #992 (issue no GitHub)
  • AlteradoFuncionascan-url-query e sua ferramenta MCP aceitam o argumento opcional facets (lista de#991

    grupos…

    scan-url-query e sua ferramenta MCP aceitam o argumento opcional facets (uma lista de IDs de grupo, ou all), que retorna contagens por grupo (status_2xx–5xx, title_missing, canonical_missing, directives_noindex/nofollow, with_outlinks) sobre os mesmos filtros, em uma única passagem. Grupos que dependem de uma projeção (interno/externo, sitemap, título duplicado/tamanho, canonical autorreferente/outro) ainda não estão incluídos.

    #991 (issue no GitHub)
  • AlteradoFuncionaVínculos de fontes do projeto, primeira fatia (#990): project-sources-link,#990

    project-sources-unlink e project-sources-list (CLI, além de seo_project_sources_link|unlink|list via MCP) registram quais IDs de recursos do provedor um projeto local usa, em sources.json ao lado de project.json. Somente offline: sem descoberta, sem chamada a provedor, sem credenciais; project.json nunca é reescrito.

    #990 (issue no GitHub)
  • AlteradoFuncionaRastreamento nativo: nova verificação IMG_BROKEN (#989, fatia 1) reporta alvos de <img>#989

    que responderam 4xx/5xx, com a página de origem como evidência. Ela lê o grafo de recursos armazenado e ignora o caso com honestidade quando nenhuma imagem foi medida.

    #989 (issue no GitHub)
  • AdicionadoFuncionaAdicionado um classificador puro de soft 404 sobre o corpo da página armazenado#988

    (classify_stored_soft404): texto vazio, uma frase de erro em uma página com pouco conteúdo e uma correspondência por simhash com um template de 404. Ainda não está ligado ao rastreamento e não emite achados; esta é a primeira fatia da issue #988.

    #988 (issue no GitHub)
  • AlteradoFuncionaRastreamentos nativos sondam alvos de canonical e hreflang que nenhum link alcançou, uma#987

    vez por alvo, após o rastreamento (no máximo 5.000). Um alvo com 4xx/5xx ou que redireciona passa a reportar CANONICAL_TARGET_ERROR, CANONICAL_TO_REDIRECT ou HREFLANG_BROKEN_TARGET, como já acontecia com alvos rastreados (#987).

    #987 (issue no GitHub)
  • AlteradoFuncionaAchados de cadeia e loop de redirecionamento de um rastreamento nativo agora trazem o#985

    caminho completo…

    Os achados de cadeia e loop de redirecionamento de um rastreamento nativo agora trazem o caminho completo de saltos (details.path), para que uma correção possa indicar cada salto a substituir. Refs #985.

    #985 (issue no GitHub)
  • AlteradoFuncionaAchados de cadeia e loop de redirecionamento de um rastreamento nativo agora também#985

    trazem…

    Os achados de cadeia e loop de redirecionamento de um rastreamento nativo agora também trazem details.inbound_links (links internos que ainda apontam para a primeira URL da cadeia, com âncoras, limitado a 20) e inbound_links_count; sem um inventário all_inlinks, o campo fica null com um motivo. Refs #985.

    #985 (issue no GitHub)
  • AlteradoFuncionaProjetos podem registrar um link para o seu núcleo semântico como fatos inseridos pelo#984

    operador (semcore_project, semcore_cluster_count, semcore_landing_mapping). O núcleo semântico continua no próprio banco e não é mesclado ao banco do projeto; a detecção nunca grava esses fatos, e um fato fornecido não pode alegar proveniência de detecção. Documentado em docs/PROJECTS.md, na seção “Linking a semantic core” (parcial, #984).

    #984 (issue no GitHub)
  • AlteradoFuncionaDesktop: a tela Link graph segue o design GraphFilters (canvas e painel de filtros).#975

    O núcleo ainda não retorna o grafo de links completo, então o canvas mostra um estado de espera honesto e os filtros ficam inertes até lá (#975).

    #975 (issue no GitHub)
  • AlteradoFuncionaOAuth do GSC: provider-auth --action cancel (CLI) e seo_provider_auth action=cancel…#964

    OAuth do GSC: provider-auth --action cancel (CLI) e seo_provider_auth com action=cancel (MCP) cancelam um registro pendente de fluxo de consentimento no navegador; status informa o fluxo pendente, quando existir. O registro do fluxo não guarda material de concessão e expira em dez minutos. Esta é a primeira fatia do #964: ainda não há início nem callback pelo navegador, então a superfície pública não cria nenhum fluxo e o acesso conectado continua sem ser afirmado.

    #964 (issue no GitHub)
  • AlteradoFuncionacrawl-site --urls/--urls-file --project agora registra o rastreamento por lista de URLs#962

    como uma execução de observer (mode=list), que aparece em project-observe e project-scans com seu artefato na pasta scans/ do projeto. Um coletor que falha é registrado como failed; progresso e retomada de execuções de lista ainda não estão cobertos (#962).

    #962 (issue no GitHub)
  • AdicionadoFuncionaAdiciona um esboço estruturado de playbook: skill-list e scenario-list retornam cada…#955

    Adiciona um esboço estruturado de playbook: skill-list e scenario-list retornam os passos ordenados de cada playbook, e skill-show/scenario-show acrescentam seus títulos e passos, para que um agente leia a forma do método sem interpretar markdown (#955). Novo comando de CLI scenario-list e ferramenta MCP seo_scenario_list.

    #955 (issue no GitHub)
  • AlteradoFuncionascan-content-search aceita --kind regex (MCP kind="regex") para buscar em#954

    documentos retidos…

    scan-content-search aceita --kind regex (MCP kind="regex") para buscar nos documentos retidos com uma expressão regular do Python. Expressões inválidas são recusadas antes da varredura; um documento que excede o orçamento de tempo do regex é reportado como indisponível, nunca como ausente.

    #954 (issue no GitHub)
  • AlteradoFuncionaChamadas ao DataForSEO com resposta perdida (erro de rede após o envio) são registradas…#949

    Chamadas ao DataForSEO cuja resposta se perde (erro de rede depois de a requisição ser enviada) são registradas no diário com cost_unknown e charge_status: unknown, assim spend-report as lista como incertas, em vez de contá-las como chamada medida de custo zero (#949).

    #949 (issue no GitHub)
  • AdicionadoFuncionaNovo comando scan-structured-blocks (CLI) e ferramenta MCP#948

    seo_scan_structured_blocks: para uma URL retida, descreve cada bloco JSON-LD (sua linha de origem, status valid / errors / warnings / parse_error, tipos, uma lista plana de propriedades, JSON de origem limitado e erros do grafo Schema.org). Funciona offline, apenas sobre o corpo completo da página retido; sem requisições de rede e sem alterações nos artefatos.

    #948 (issue no GitHub)
  • AlteradoFuncionacrawl-site sem projeto que grava um artefato de scan em SQLite agora compartilha seu#942

    teto de requisições por host com outros rastreamentos simultâneos do mesmo host, por meio de um cronograma privado no diretório de estado do usuário (~/.config/seohead/.origin-pacing.sqlite). Antes, rastreamentos sem projeto rodavam sem controle de ritmo entre processos.

    #942 (issue no GitHub)
  • AlteradoFuncionaPerfis do crawl-site (#941): crawl-profile list mostra os nomes dos perfis salvos e…#941

    Perfis do crawl-site (#941): crawl-profile list imprime os nomes dos perfis salvos e crawl-profile delete NAME remove um; ambos imprimem JSON e recusam nomes desconhecidos, com a lista dos perfis salvos.

    #941 (issue no GitHub)
  • AlteradoFuncionaPerfis do crawl-site (#941): --save-profile NAME --config FILE armazena uma#941

    configuração validada…

    Perfis do crawl-site (#941): --save-profile NAME --config FILE armazena uma configuração de rastreador validada como perfil nomeado (recusado quando traz cabeçalhos de credencial); --profile NAME rastreia com ele, e --set ainda se aplica por cima. Os perfis ficam em ~/.config/seohead/crawl-profiles ou no diretório indicado por SEOHEAD_CRAWL_PROFILES. Listar e excluir perfis não fazem parte desta fatia.

    #941 (issue no GitHub)
  • AlteradoFuncionacompare.v1 agora lista páginas rastreadas em apenas um dos lados (url_sets:#938

    only_in_before, only_in_after, contagens). Quando qualquer um dos rastreamentos é parcial, url_sets.unproven fica verdadeiro, para que a ausência não seja apresentada como prova.

    #938 (issue no GitHub)
  • AlteradoFuncionaCada salto de cadeias de redirecionamento e canonical registra status, próxima Location#930

    (redirecionamentos)…

    Cada salto de cadeias de redirecionamento e canonical registra o status, a próxima Location (redirecionamentos) e o tempo de resposta, para que a cadeia de uma URL seja lida a partir de evidências armazenadas, sem nova requisição (#930).

    #930 (issue no GitHub)
  • AlteradoFuncionaLoops de redirecionamento em cadeias por URL terminam com um passo marcador ({"url": ..., "loop": true}#930

    ) que não é buscado de novo, então a URL repetida fica visível nas evidências armazenadas; final_url continua apontando para o último salto buscado (#930).

    #930 (issue no GitHub)
  • AdicionadoFuncionaExpõe as etapas create e scan-ingest do ledger de correções pelo CLI e pelo MCP…#926

    Expõe as etapas de criação e de ingestão de scan do ledger de correções pelo CLI e pelo MCP: remediation-create / seo_remediation_create cria um ledger novo e vazio, vinculado a um projeto (producer_build precisa ser um SHA Git completo de 40 caracteres; caminhos existentes são recusados), e remediation-ingest / seo_remediation_ingest ingere uma auditoria salva como baseline/histórico sem rodar novo rastreamento (a reingestão da mesma revisão é idempotente). A lógica de armazenamento não muda; esta é a primeira fatia do #926.

    #926 (issue no GitHub)
  • AlteradoFuncionacrawl_site e as execuções de scan informam effective_max_requests_per_second e#925

    warnings: um aviso quando a taxa efetiva está acima de 2 req/s (o limite é estritamente maior que 2). A CLI imprime o mesmo aviso no stderr; o JSON no stdout e os padrões não mudam. O pacer não foi alterado.

    #925 (issue no GitHub)
  • AlteradoFuncionaLog estruturado de eventos do projeto (events.jsonl): eventos somente de acréscimo com#923

    source, actor e…

    Log estruturado de eventos do projeto (events.jsonl): eventos somente de acréscimo com campos source, actor e texto limitado, lidos do mais recente para o mais antigo, em páginas, com filtros por source e por texto. Expostos como project-event-append / project-event-page na CLI e seo_project_event_append / seo_project_event_page via MCP (issue #923).

    #923 (issue no GitHub)
  • AdicionadoFuncionaAdiciona o comando ai-column e a ferramenta MCP seo_ai_column, a primeira fatia da

    coluna personalizada com IA (refs #1012). Sobre páginas selecionadas de um scan retido, ou sobre itens normalizados fornecidos, prepara um plano limitado a partir do título, dos cabeçalhos e de um trecho do texto, com estimativa de tamanho baseada em caracteres (sem preço aplicado) e o escopo de consentimento que o agente chamador deve respeitar antes de qualquer envio. Valores por URL fornecidos são validados contra o hash de origem de cada página; valores ausentes, desatualizados, vazios ou grandes demais são reportados como tal e nunca preenchidos. Um CSV opcional, seguro contra fórmulas, exporta a coluna. O SEOHEAD não guarda chave de provedor e não faz nenhuma chamada a modelo.

  • AlteradoFuncionaCompartilha os abridores SQLite somente leitura e de escrita em seohead.core.sqlite.

    Leitores de armazenamento, o importador de scans, o arquivo do GSC, o store de fontes, o store de junção de evidências e as duas classes de verificações agora abrem seus bancos por meio de um único helper para conexão, row factory e PRAGMAs. As duas classes de verificações fecham suas conexões explicitamente. O comportamento não muda; a normalização de caminhos e a ordem dos PRAGMAs permanecem em cada ponto de chamada.

  • AlteradoFuncionaCorreções de comportamento a partir de uma revisão de verificações, fontes de dados e

    importação de evidências.

    Mudanças de comportamento intencionais nesses caminhos: - Cadeias de redirecionamento com exatamente o limite de saltos (padrão 20) agora são resolvidas, em vez de reportadas como não resolvidas. A verificação de loop roda antes da verificação de limite, tanto na resolução de cadeias quanto nas caminhadas do caminho de saltos. - As verificações de confiança e citação do EEAT comparam hosts de destino com a porta (netloc), como a lógica de host dos links internos. Sites com portas explícitas podem mudar resultados. - As verificações de palavras-chave do llms.txt casam termos ASCII como palavras inteiras, com plural opcional, então rapid, Showcase e Toolbar não passam mais. Radicais em cirílico ainda casam como substring. - A captura de navegação mapeia o motivo reload para refresh_navigation. Motivos solicitados não mapeados, como pageBlockInterstitial, são registrados como observações de frame que o validador aceita. - A detecção de tecnologia trata uma implicação negada (["not", X]) como não implicando nada. - A importação de evidências rejeita nomes de métricas declarados em duplicidade, e a descoberta no Search Console usa as linhas que recebe. - As novas tentativas do Yandex Cloud dormem apenas entre uma tentativa e outra. As novas tentativas de query-analytics do Yandex Webmaster recuam antes da próxima tentativa. - A construção de schema repassa seu timeout ao cliente HTTP (padrão inalterado). - O armazenamento de recibos de entrega é criado com modo 0600 antes de o SQLite abri-lo. - Execuções de grafo semântico são serializadas, porque o conjunto de stop-words é estado de módulo. O runner semântico reporta erros de SQLite como ok: false, em vez de lançar exceção. - O parser de erros do CrUX tolera corpos de resposta que não são objetos. - Removida uma guarda sqlite3 is None inalcançável no ledger.

  • AlteradoFuncionaDesktop: uma tela de Backlinks no layout design-v2.

    Mostra o estado de espera honesto até que o núcleo armazene um perfil de links do projeto (#999); sem linhas de exemplo, e os filtros de grupo ficam desativados pelo mesmo motivo.

  • AlteradoFuncionaTela Crawler do desktop: adiciona o banner de resultados temporários com o endereço

    selecionado e o texto de status (exibido só quando um rastreamento sem projeto retorna resultados), move as ações de limpar e salvar como projeto para um menu de overflow abaixo de 1000 px, mantém o campo de endereço e a faixa de abas de verificação utilizáveis em larguras estreitas, rola o cabeçalho de resultados em vez de espremer suas colunas e dá à barra de status da shell o mesmo padding direito de 8 px nos temas escuro e claro.

  • AlteradoFuncionaDesktop: telas de estados fatais por canvas (ErrorsCore): núcleo ausente, pouco espaço em

    disco e sem permissão de escrita são mostrados a partir de fatos reais; a versão do núcleo e a integridade do scan mostram o selo neutro “indisponível nesta versão do núcleo” até que o núcleo os informe.

  • AlteradoFuncionaDesktop: o menu da linha de URL e o menu do cabeçalho de coluna, os grupos Edit, Scan e

    Window da barra de menus, e os menus de contexto de achados e tarefas seguem o quadro Menus do canvas. Itens que o núcleo ainda não oferece continuam visíveis, desativados, com o motivo na dica de ferramenta.

  • AlteradoFuncionaDesktop: a tela “Export and reports” segue o canvas de design ProjExport (escolha de

    dataset e formato, card de pasta, exportações recentes). Datasets e formatos que o núcleo ainda não consegue exportar (compare, tasks, PDF) aparecem como indisponíveis; o botão de execução fica desativado até que a exportação esteja ligada (#1191).

  • AlteradoFuncionaNeutraliza TAB e CR no início de identificadores do inventário de marketing e nos CSVs de

    revisão de rascunhos de meta description, com o mesmo prefixo de apóstrofo já aplicado a =, +, - e @. Ambas as proteções agora usam seohead.core.tabular.neutralize_formula.

  • AlteradoFuncionaRequisições com credenciais de provedores (Arsenkin, Metrika, Yandex Cloud, IndexNow…

    Requisições com credenciais a provedores (Arsenkin, Metrika, Yandex Cloud, IndexNow, Topvisor, destinos de BI) não seguem mais redirecionamentos HTTP, então o cabeçalho Authorization nunca é reenviado a outro host. Agora, um redirecionamento aparece como erro HTTP do provedor.

  • AdicionadoFuncionaAdiciona o formato de redirecionamento csv (linhas source,target,301, com aspas

    quando necessário) ao generate_rule e à ajuda da CLI redirects-generate. O formato wordpress-redirection não entrou porque a sintaxe de importação dele ainda não foi verificada (#998).

  • AlteradoFuncionaO registro de execuções (runs.jsonl) passa a rotacionar ao atingir um limite de tamanho

    (5 MiB por padrão; SEOHEAD_RUN_LOG_MAX_BYTES altera esse valor). A geração anterior é mantida como runs.jsonl.1, e as leituras cobrem os dois arquivos, então as buscas de reuso ainda encontram chamadas recentes.

  • AlteradoFuncionaOrganiza a aba Schema do card de URL no desktop na estrutura de canvas do design-v2

    (lista de blocos, árvore de blocos, verificações). O núcleo devolve apenas a contagem de blocos JSON-LD por URL, então as colunas mostram estados de espera honestos, ligados à issue 948 do núcleo, e as contagens conhecidas continuam reais; nenhum bloco de exemplo é exibido.

9 de outubro de 2026

4 adicionado4 alterado
  • AdicionadoFuncionaAdiciona rótulos do terminal em RU/EN conforme o idioma, bloco de progresso da varredura#951

    atual, seleção explícita…

    Adiciona rótulos do terminal em RU/EN conforme o idioma, um bloco de progresso da varredura atual, seleção explícita de varredura e saída compacta do observador.

    #951 (issue no GitHub)
  • AlteradoFuncionaVarreduras salvas abrem de forma leve para leitura (#931).#931

    scan-status, scan-url-detail, scan-link-inspect e o observador de projeto (project-scans, project-observe) não validam mais o artefato inteiro a cada abertura: verificam identidade, schema, versão e a linha de cabeçalho, obtêm os contadores via SQL (GROUP BY sobre pages_status) e informam isso em um campo aditivo validation ("light" ou "full"). A validação completa roda sob pedido (full_validation: true em scan-status, ou --input '{"input_path": "...", "full_validation": true}' na CLI) ou quando os mesmos bytes (caminho, tamanho, mtime, estado do WAL, hash do cabeçalho) já foram validados completamente no processo. Uma varredura que falha nas verificações leves é recusada com o mesmo erro de antes, e todo caminho que grava ou registra evidências continua validando por completo. scan-url-detail executa a busca do alvo de redirecionamento (sem índice em responses.effective_url_id) com orçamento de 0,5 s e informa responses.redirect_target_lookup como skipped, em vez de varrer uma tabela grande.

    #931 (issue no GitHub)
  • AdicionadoFuncionaAdiciona estado do MCP compartilhado e auditado, com revogação na inicialização e em#929

    tempo real; expõe a presença segura de clientes pela CLI.

    #929 (issue no GitHub)
  • AdicionadoFuncionaAdiciona registro de clientes com permissão explícita, prévias, gravações atômicas,#929

    backups verificados e restauração sem conflitos.

    #929 (issue no GitHub)
  • AdicionadoFuncionaAdicionado scan-url-query (MCP seo_scan_url_query): leitura somente leitura,#927

    filtrada, ordenada e paginada no servidor, de toda a tabela de páginas de uma varredura salva, com total, filtered_total (null mais filtered_total_state: capped quando a contagem excede seu orçamento de tempo), projeção de colunas, rótulos de cobertura da varredura, o formato seohead.scan-url-query.v1 e um reason_code legível por máquina em toda falha. No máximo 200 linhas por chamada; ordenação por url, status_code, page_ordinal ou url_id usa índices, e qualquer outra coluna exige um filtro que deixe no máximo 100.000 linhas (senão, sort_not_indexed). A varredura é aberta com verificação leve de identidade e de geração de schema, não com validação completa, e nunca é modificada.

    #927 (issue no GitHub)
  • AlteradoFuncionascan-link-inspect --view links (MCP seo_scan_link_inspect) pagina os links de saída#924

    ou de…

    scan-link-inspect --view links (MCP seo_scan_link_inspect) pagina os hiperlinks de saída ou de entrada de uma URL, localizada pelo endereço e não pelo ID do documento: âncora, rel com as flags nofollow/sponsored/ugc, interno/externo, posição armazenada, atributo target e o status HTTP do outro lado (null quando essa página não foi varrida). Filtra por tipo de link, follow, classe de status e trecho de texto; offset/limit até 200; total/filtered_total são exatos ou marcados como capped. A varredura é aberta em modo somente leitura, sem validação completa, e as falhas trazem um reason_code legível por máquina (url_not_found, scan_not_available, url_not_scanned, links_not_retained). Views e campos existentes não mudam.

    #924 (issue no GitHub)
  • AlteradoFuncionaLayout do pacote reorganizado, sem shims de compatibilidade: seohead.servers agora é…

    Layout do pacote reorganizado, sem shims de compatibilidade: seohead.servers virou seohead.mcp, seohead.tools virou seohead.checks, seohead.bot e seohead.remote_api foram para seohead.integrations, a CLI fica no pacote seohead.cli (com seohead.cli.terminal_progress), os módulos raiz compartilhados (models, graph, filesystem, runlog, verification, canonical_policy, input_contracts, job_contracts, provider_matrix) foram para seohead.core, e a proveniência da build foi para seohead._build.provenance. examples/ e config.example.json foram para docs/examples/; PROVENANCE.md e TRADEMARKS.md foram para docs/legal/. Os comandos seohead e sf-analyzer não mudaram; imports Python com os caminhos antigos precisam ser atualizados.

  • AlteradoFuncionaReescreve o README em torno da instalação, de três caminhos de início rápido (do

    rastreamento nativo ao relatório, das exportações offline do Screaming Frog, e de projeto com agente), de um mapa de funcionalidades por área, de uma visão geral da CLI, da configuração do MCP para Claude Code e Claude Desktop, do app desktop complementar e da fronteira entre o que é medido e o que não é, com capturas reais do terminal em docs/assets/, feitas a partir de um fixture local de QA e do fixture sintético de exportação. Adiciona docs/CLI.md, que agrupa cada comando registrado por tarefa, com suas anotações de rede, escrita e pago (um teste de consistência agora falha se algum comando estiver faltando), e docs/WORKFLOWS.md, que documenta os comandos de execução de workflow, inbox e registro de monitor, antes apenas referenciados.

8 de outubro de 2026

1 adicionado10 alterado1 corrigido
  • CorrigidoFuncionaMantém a contabilização de bytes de HTML/DOM retidos local à transação e incremental, em#914

    vez de reler todos os corpos armazenados a cada resposta única. Gravadores reabertos reconstroem o contador uma vez; deduplicação, rollback, savepoints e limites de retenção de corpos continuam intactos.

    #914 (issue no GitHub)
  • AlteradoFuncionaRelatórios de BI mantêm estados de coleta de provedores não verificados e sinalizadores#833

    de qualidade como desconhecidos em métricas, cobertura e manifestos; amostragem, aplicação de limiares ou truncamento confirmados são parciais. Coortes de busca versus sessões exigem qualidade de coleta explícita, medições de contagem não negativas e escopos de origem qualificados, e mantêm a identidade de origem, a atribuição, o escopo de busca e a política de calendário de cada eixo. O pacote sintético de relatórios continua offline; a aceitação nativa do Sheets e do Looker segue separada.

    #833 (issue no GitHub)
  • AlteradoFuncionaVarreduras nativas de site em SQLite aceitam max_urls=0 para coletar até esgotar a fila…#818

    Varreduras nativas de site em SQLite aceitam max_urls=0 para coletar até a fila se esgotar, e max_depth=-1 para desativar o limite de profundidade. Orçamentos de tempo e de HTTP continuam configuráveis separadamente, as guardas de armazenamento e a interrupção com retomada continuam ativas, e rotas materializadas legadas recusam uma população de URLs ilimitada.

    #818 (issue no GitHub)
  • AlteradoFuncionaVarreduras somente de sitemap também preservam o limite de URLs desativado, em vez de#818

    recusar seu primeiro…

    Varreduras somente de sitemap também preservam o limite de URLs desativado, em vez de recusar o primeiro membro declarado quando o limite configurado é zero.

    #818 (issue no GitHub)
  • AlteradoFuncionaTaxas de requisição finitas explícitas acima do padrão de 2 requisições/s agora chegam à#818

    faixa…

    Taxas de requisição finitas explícitas acima do padrão de 2 requisições/s agora chegam também à faixa compartilhada de controle de ritmo por origem do projeto, além do limitador por varredura. Varreduras paralelas continuam reservando uma única agenda comum por host, em vez de multiplicar a taxa dele.

    #818 (issue no GitHub)
  • AlteradoFuncionaInterromper a análise nativa agora retorna um resultado interrompido explícito e#754

    retomável, e mantém…

    Interromper a análise nativa agora retorna um resultado interrompido explícito e retomável, e preserva as páginas capturadas, em vez de vazar um traceback de KeyboardInterrupt.

    #754 (issue no GitHub)
  • AlteradoFuncionaRegenera o catálogo de projetos empacotado após a atualização do cenário do provedor Bing.#754 (issue no GitHub)
  • AlteradoFuncionaRejeita linhas malformadas de resposta do Bing Webmaster em vez de reportar um resultado#753

    vazio como completo. Preserva os dados brutos da resposta, as linhas de origem e as contagens exatas devolvidas nas evidências salvas do provedor. Respostas de contagem de links mantêm o envelope de página documentado e reportam populações de várias páginas como parciais quando apenas uma página solicitada foi coletada.

    #753 (issue no GitHub)
  • AlteradoFuncionaReconhece o fallback compartilhado e já existente de conta de serviço do Google na#753

    prontidão do GA4…

    Reconhece o fallback compartilhado e já existente de conta de serviço do Google na prontidão do provedor GA4 e na descoberta de credenciais. Mantém as permissões da conta e o acesso aos alvos como não verificados, informa explicitamente credenciais malformadas e preserva o suporte a bearer token OAuth sem exigir as duas fontes.

    #753 (issue no GitHub)
  • AlteradoFuncionaVincula referências de capacidades headless ao isolamento de execução nativa e à#743

    fronteira pública de roteamento do rastreamento externo, distinguindo implementação interna de disponibilidade em CLI/MCP, sem alterar o comportamento do rastreamento nem as alegações de capacidade.

    #743 (issue no GitHub)
  • AdicionadoFuncionaAdiciona paginação limitada de execuções finalizadas ao project-observe na CLI e no

    MCP, mantendo visível cada registro de execução em andamento armazenado. As páginas preservam os IDs exatos das execuções e a ordem reversa de admissão; contagens e metadados de retenção descrevem o armazenamento atual de 100 registros, não o histórico completo. A leitura nunca altera os estados de execução armazenados. Entradas JSON da CLI mantêm sua paginação e seu escopo de projeto, a menos que uma flag nomeada explícita os substitua.

  • AlteradoFuncionaTrata Ctrl+C em toda a transição nativa pós-coleta, inclusive ao abrir a varredura salva,

    nas fases opcionais de acompanhamento, na análise e na finalização. Capturas não concluídas mantêm seus dados e o checkpoint retomável, e retornam um resultado JSON interrompido explícito. Uma interrupção após o commit final preserva o artefato concluído e informa a disponibilidade real da auditoria. A retomada explícita conclui o trabalho pós-coleta pendente mesmo com a fronteira esgotada, preservando as flags existentes de omissão de evidências e as entradas de sitemap retidas.

7 de outubro de 2026

4 adicionado4 alterado1 corrigido
  • AdicionadoFuncionaAdiciona um fixture descartável de aceitação em Linux para execução real de worker SSH#754

    com chave…

    Adiciona um fixture descartável de aceitação em Linux para execução real de worker via SSH com chave, downloads de API/TLS autenticados e ENOSPC do worker nativo em um tmpfs limitado apenas a jobs. Preserva a fila e as evidências, e exige um resultado explícito de não sucesso, sem reexecução, antes de um novo job de recuperação em JS. Esclarece as medições locais de ciclo de vida em relação às evidências de SSH e de contenção do sistema operacional.

    #754 (issue no GitHub)
  • AlteradoFuncionaPreserva evidências parciais de JavaScript em resultados de jobs remotos, inclusive a#754

    correção somente leitura de jobs antigos já finalizados, sem alterar artefatos retidos nem orçamentos de renderização. Verifica o backup e a restauração reais da fila por meio de status autenticado, downloads e idempotência persistente; mantém o fixture de recuperação de duas páginas com renderização completa dentro de seus orçamentos finitos existentes.

    #754 (issue no GitHub)
  • AlteradoFuncionaRetorna exit 130 sem traceback quando SIGINT interrompe a saída JSON final após a

    conclusão…

    Retorna exit 130 sem traceback quando SIGINT interrompe a saída JSON final depois que um handler já foi concluído. Artefatos retidos permanecem inalterados; um fluxo de saída truncado nunca é reportado como sucesso.

  • AdicionadoFuncionaRegistra a estratégia de área de conteúdo usada para gerar hashes retidos e contagens de

    tokens, em vez da estratégia de área padrão do parser. Seletores explícitos e exclusões agora têm proveniência de extração correspondente, mesmo quando o parser da página usou sua região padrão.

  • CorrigidoFuncionaMantém arquivos de staging SQLite nativos não publicados fora do histórico de varreduras

    e dos candidatos à retenção; continua reportando arquivos publicados inválidos e permite varreduras ocultas comuns nomeadas pelo usuário.

  • AdicionadoFuncionaAdicionada coleta nativa SQLite somente de sitemap: um sitemap explícito define a

    população completa de URLs solicitada, sem fallback para a página inicial, expansão por hiperlinks ou expansão por alvos de redirecionamento. Populações de sitemap vazias, incompletas ou acima do orçamento são interrompidas explicitamente, e a retomada reaproveita a população retida sem baixar o XML novamente.

  • AlteradoFuncionaPreserva registros de execução de projeto distintos para capturas nativas simultâneas e

    compartilha, dentro do projeto, um gate de despacho local de 2 requisições/s para o mesmo host público; expõe a cada observador o tipo de origem de cada execução, a origem, a impressão digital da configuração e o limite de taxa agregado.

  • AdicionadoFuncionaAdiciona busca literal offline sobre HEAD, HTML, texto do corpo e marcação selecionada

    por CSS retidos, com cobertura estática/renderizada explícita, corpos ausentes marcados como desconhecidos, trechos redigidos opcionais e paginação verificada por integridade em novos pacotes locais de resultados.

  • AlteradoFuncionaPreserva as configurações próprias de um rastreamento salvo do Screaming Frog ao

    exportá-lo: o load-crawl não injeta mais a configuração atual do spider. Execuções ao vivo de spider e de lista continuam recebendo seus perfis explícitos por execução.

6 de outubro de 2026

9 adicionado14 alterado9 corrigido
  • AlteradoFuncionaFaz os testes próprios de captura externa resolverem de forma consistente seus virtual#896

    hosts de loopback em todos os sistemas operacionais, sem alterar a política de rede de produção.

    #896 (issue no GitHub)
  • CorrigidoFuncionaMantém a entrada do terminal funcionando acima do limite de descritores do select, e#896

    impede que Delete ou sequências de controle não suportadas cancelem notas não salvas.

    #896 (issue no GitHub)
  • AlteradoFuncionaRetém eventos versionados de navegação do navegador, com omissões limitadas, estado da#826

    captura, política do renderizador e proveniência da URL. Distingue redirecionamentos HTTP observados, navegação por script, histórico ou fragmento no Chromium e causas desconhecidas, sem afirmar cliques humanos.

    #826 (issue no GitHub)
  • AdicionadoFuncionaExpõe as mesmas evidências em render-check e em relatórios limitados de scan-navigation#826

    offline; preserva observações parciais quando a renderização falha.

    #826 (issue no GitHub)
  • AlteradoFuncionaPreserva a compatibilidade com rollback ao reter evidências de navegação em configurações#826

    de…

    Preserva a compatibilidade com rollback ao reter as evidências de navegação dentro de configurações de renderizador extensíveis; valida a codificação anterior, de pré-lançamento, sem enfraquecer as verificações de proveniência e sem tratar eventos observados como política do renderizador.

    #826 (issue no GitHub)
  • CorrigidoFuncionaMantém populações resumidas grandes e aninhadas, inclusive histogramas de profundidade,#818

    em companions…

    Mantém populações resumidas grandes e aninhadas, inclusive histogramas de profundidade, nos companions PDF completos, sem cobrá-las do orçamento limitado de metadados de exibição. Preserva destinos nomeados, marcadores (outlines) e links internos ao reescrever os links portáteis do companion, clonando o documento PDF completo.

    #818 (issue no GitHub)
  • AdicionadoFuncionaAdiciona pdf_policy="overview-v1" explícito para requisições PDF audit.v2 retidas.#818

    A primeira página distingue as contagens completas de origem, exibidas e omitidas; prefixos de exibição determinísticos mantêm os estados e motivos de cobertura completos e linkam para o JSON completo de auditoria em streaming e para os companions CSV de achados, páginas e escopo. Um manifesto de hashes e contagens registra a proveniência e os limites de recursos. Destinos existentes são recusados, as exportações são preparadas em staging, e o marcador de conclusão do PDF só é publicado depois que todos os companions obrigatórios são validados. O comportamento padrão do PDF permanece inalterado: a visão geral nunca é selecionada silenciosamente nem descrita como um PDF exaustivo. Veja docs/PDF_OVERVIEW.md para os limites exatos e a semântica de falhas.

    #818 (issue no GitHub)
  • AdicionadoFuncionaAdiciona a operação somente leitura page_views do provedor GA4 por data, hostname e#782

    caminho…

    Adiciona a operação somente leitura page_views do provedor GA4 para contagens de visualização por data, hostname e caminho visitado, independentemente das sessões de página de entrada. Reutiliza as credenciais, o transporte e o leitor paginado de relatórios do GA4 já existentes, com novas tentativas limitadas, resultados de cota e de permissão, metadados explícitos de fuso horário, amostragem e limiar, e vinculação de URL à origem declarada. As evidências restritas salvas são normalizadas pela junção e pelo pipeline de BI já existentes; tráfego ausente continua indisponível, em vez de virar zero.

    #782 (issue no GitHub)
  • CorrigidoFuncionaMantém as atualizações do observador limitadas: reutiliza a cobertura por site, projeta a#777

    atividade ao vivo do coletor separadamente e pagina os achados do audit.v2 sem materializar coleções não relacionadas do grafo.

    #777 (issue no GitHub)
  • AlteradoFuncionaPreserva todo coletor ativo em um histórico limitado e publica janelas de contadores#777

    medidos…

    Preserva todo coletor ativo em um histórico limitado, publica janelas de contadores medidos com carimbo de data/hora e distingue contadores não medidos de zero. Transmite o progresso verificado do Screaming Frog em tempo real, limitando os dois pipes de diagnóstico.

    #777 (issue no GitHub)
  • AdicionadoFuncionaAdiciona páginas somente leitura de checklist, de detalhe de tarefa e de varredura#777

    retida, além de escopo explícito de métodos aplicáveis e uma projeção da inbox mais recente.

    #777 (issue no GitHub)
  • CorrigidoFuncionaMantém execuções de sitemap explicitamente associadas como distintas: contadores em#777

    andamento permanecem desconhecidos, e as medições finais contam os documentos de sitemap analisados separadamente das URLs declaradas, dos erros e dos truncamentos.

    #777 (issue no GitHub)
  • AlteradoFuncionaObserva recibos de artefatos de checklist por meio de metadados de identidade de arquivo#777

    protegidos, sem recalcular o hash dos bytes retidos a cada atualização. Leituras explícitas de cobertura mantêm a verificação dos bytes; evidências alteradas ou legadas e não verificadas continuam visíveis como desatualizadas ou não verificadas.

    #777 (issue no GitHub)
  • CorrigidoFuncionaMantém recibos históricos de prioridade vinculados ao escopo original de seus itens#777

    quando novas tarefas são adicionadas após a preparação, e valida cada candidato completo de cobertura antes da publicação atômica. Leituras de detalhe de concorrentes com escopo preservam a verificação passiva somente de metadados.

    #777 (issue no GitHub)
  • AdicionadoFuncionaAdiciona comparação explícita de auditorias salvas em disco, com resultados NDJSON#762

    completos, ordenação determinística, identidades de origem, checksums por arquivo e conservação de achados antes e depois. Comparações grandes de audit.v2 exigem um novo diretório de saída; identidades duplicadas e colisões na correspondência de URLs falham, em vez de perder linhas.

    #762 (issue no GitHub)
  • CorrigidoFuncionaMantém a verificação direcionada de audit.v2 limitada quando há linhas duplicadas, retém#762

    a identidade de varredura validada nos documentos selecionados e recusa identidades conflitantes, ou rastreamentos posteriores inválidos, como prova de correção.

    #762 (issue no GitHub)
  • AdicionadoFuncionaAdiciona compressão gzip em streaming, opcional, para arquivos NDJSON completos de#762

    compare.v2, com bytes comprimidos determinísticos, hashes exatos do arquivo comprimido e contagens decodificadas de linhas e bytes. Adiciona um leitor limitado que valida exportações simples ou em gzip e rejeita fluxos danificados ou contagens divergentes do manifesto; a saída simples continua sendo o padrão.

    #762 (issue no GitHub)
  • CorrigidoFuncionaMantém a compatibilidade da comparação de corpus salvo como desconhecida quando uma das#762

    flags de completude está ausente, e avisa explicitamente sobre corpora parciais conhecidos. Preserva os IDs e os motivos de verificações puladas e desativadas junto com as variações de achados, para que medições ausentes não sejam apresentadas como correção verificada.

    #762 (issue no GitHub)
  • AlteradoFuncionaFaz o observador de projeto no terminal navegar por detalhes legíveis de tarefa, método,#752

    dados…

    Faz o observador de projeto no terminal navegar por detalhes legíveis de tarefas, métodos, dados estruturados, varreduras, execuções, inbox e evidências retidas, com páginas limitadas e cobertura de escopo honesta. Leituras de armazenamento e envios explícitos de notas ficam fora do loop de entrada.

    #752 (issue no GitHub)
  • AlteradoFuncionaPreserva rascunhos separados de notas e de objetivos durante a sessão, com edição por#752

    cursor…

    Preserva rascunhos separados de notas e de objetivos durante a sessão, oferece edição com cursor, mantém colagens grandes sem truncar, exibe recibos de salvamento em todos os layouts e imprime rascunhos não salvos após uma saída normal do terminal, para recuperação.

    #752 (issue no GitHub)
  • AdicionadoFuncionaAdiciona navegação explícita de cobertura e artefatos do próprio site e dos concorrentes,#752

    mantém o site selecionado nas páginas de varredura e de achados, exibe sugestões recentes de concorrentes baseadas em notas e mantém o progresso medido da coleta visível em terminais compactos. Amostras antigas não são mais animadas como progresso ao vivo.

    #752 (issue no GitHub)
  • AdicionadoFuncionaAdiciona um inventário versionado de capacidades headless gerado das configurações reais#743

    do rastreador…

    Adiciona um inventário versionado de capacidades headless, gerado a partir das configurações reais do rastreador, com referências de implementação, CLI/MCP, testes e lacunas de aceitação explícitas.

    #743 (issue no GitHub)
  • AdicionadoFuncionaAdiciona um benchmark HTML/JavaScript opcional, em origem própria, com fases congeladas e#743

    orçamentos de memória da árvore de processos, de disco e de recuperação. Navegadores reais criam os DOMs medidos; o perfil, por si só, não estabelece a capacidade de JavaScript de sites grandes.

    #743 (issue no GitHub)
  • CorrigidoFuncionaCorrige o argumento de streaming não suportado na ponte JavaScript nativa e preserva#743

    contadores de renderização já observados durante o cancelamento gracioso e a retomada.

    #743 (issue no GitHub)
  • AlteradoFuncionaPermite que o log-scan consuma caminhos de varredura nativa retidos e companions do#711

    audit.v2 sem materializar o JSON legado. Transmite achados de consistência, mantém a pertinência de páginas nativas e a deduplicação de achados em disco, preserva contagens exatas de anomalias e limita apenas os exemplos. Informa explicitamente a ausência do rastro nativo de decisões de exclusão.

    #711 (issue no GitHub)
  • AlteradoFuncionaReconhece um achado de lastmod do sitemap em todo o site na origem sem caminho do site#711

    medido, quando nenhuma página inicial foi rastreada. A exceção exige evidência de resumo do sitemap correspondente e não isenta achados de página, hosts não relacionados ou caminhos de destino não suportados.

    #711 (issue no GitHub)
  • AlteradoFuncionaCompara varreduras audit.v2 retidas por chave exata e índice ordinal, sem duplicar

    payloads…

    Compara varreduras audit.v2 retidas por meio de uma chave exata e de um índice ordinal, sem duplicar payloads de páginas e achados no armazenamento temporário do SQLite. Linhas completas, exportações determinísticas simples ou gzip, identidades de origem e entradas legadas continuam suportadas. Os leitores de auditoria fixam o snapshot validado por meio de leituras indexadas de linhas.

  • AlteradoFuncionaReverter saídas de comparação em falha tardia de publicação e recusar destinos…

    Reverte os membros de saída de comparação próprios em caso de falha tardia na publicação e recusa destinos criados em concorrência; o manifesto continua sendo o marcador final de confirmação do pacote.

  • AlteradoFuncionaDescrever a entrada pública como engenharia de SEO configurável com agentes e…

    Faz a página de entrada pública descrever a engenharia de SEO configurável com agentes e vincula toda a superfície de funcionalidades aos seus métodos, entradas e limites de evidência. Corrige orientações desatualizadas sobre o modo nativo/SF, a cobertura de projetos e a remediação. Documenta separadamente a planilha de trabalho do desenvolvedor, escrita por agentes e distinta da saída factual de relatórios, incluindo critérios de aceitação revisados e links de origem.

  • CorrigidoFuncionaRestaurar a paridade do relatório legível entre entradas audit.v2 em streaming e o JSON…

    O Markdown agora usa um único renderizador incremental, incluindo explicações de verificações indisponíveis, registros de exclusão e notas finais de cobertura. O XLSX compartilha um único layout de metadados e grava problemas e páginas em planilhas somente de gravação, de tamanho limitado, preservando todas as planilhas, colunas, filtros, gráficos e contagens de origem. Problemas suprimidos retidos podem ser reproduzidos sem materializar a coleção, e URLs de execução ausentes usam o mesmo fallback para a primeira página.

  • AlteradoFuncionaRotular a proveniência de auditorias em PDF independentemente do esquema compartilhado…

    Rotula a proveniência das auditorias em PDF independentemente do esquema compartilhado de auditoria: rastreador nativo, exportações do Screaming Frog ou um coletor SF explicitamente identificado, e coletor desconhecido. Uma auditoria nativa que usa o esquema do SF Analyzer não recebe mais um cabeçalho do Screaming Frog.

  • AlteradoFuncionaTransmitir linhas de escopo de problemas suprimidos para CSV em vez de acumular…

    Transmite as linhas de escopo de problemas suprimidos para CSV, em vez de acumular suas explicações renderizadas na memória. As exportações completas de exclusão mantêm a ordem e os fatos de origem, enquanto a alocação permanece limitada para grandes coleções de exclusões retidas.

5 de outubro de 2026

1 alterado
  • AlteradoFuncionaConciliar cada linha de lacuna de cobertura pela célula Mode real, validar…#830

    Concilia cada linha de lacuna de cobertura a partir da sua célula Mode real, valida as referências de verificações e ferramentas cobertas contra os registros públicos e gera prioridades a partir das linhas não resolvidas.

    #830 (issue no GitHub)

4 de outubro de 2026

56 adicionado75 alterado5 corrigido
  • AdicionadoFuncionaAdicionar uma projeção offline de progresso GSC de marca e sem marca, sensível ao Unicode…#880

    Adiciona uma projeção offline de progresso GSC de marca e sem marca, com aliases explícitos sensíveis ao Unicode, CTR ponderado compatível e faixas rotuladas de posição média.

    #880 (issue no GitHub)
  • AdicionadoFuncionaAdicionado agrupamento opcional de tarefas com check_assignment para URLs de template…#878

    Adicionado agrupamento opcional de tarefas com check_assignment para mapeamentos declarados de URL de template ou componente, ou para segmentos de crawl validados. Itens agrupados mantêm contagens de ocorrências e de URLs, evidências limitadas, proveniência do agrupamento, escopo de verificação e os estados declarado, candidato, confirmado ou não atribuído.

    #878 (issue no GitHub)
  • AdicionadoFuncionaAdicionar mapas opcionais de comparação de releases url-correspondence.v1 com origem e#877

    URLs…

    Adiciona mapas opcionais de comparação de releases url-correspondence.v1, com pares declarados de origem e URL, recusa de colisões, proveniência de dados das páginas e saída release_review.v1.

    #877 (issue no GitHub)
  • AdicionadoFuncionaAdicionar uma projeção offline de coortes de publicação qualificada por evidências…#876

    Adiciona uma projeção offline de coortes de publicação qualificada por evidências, com proveniência de datas, inventário de autores, observações de provedores rotuladas e janelas de idade opcionais.

    #876 (issue no GitHub)
  • AdicionadoFuncionaAdicionar um inventário offline de CTAs e formulários incorporados para HTML fornecido…#875

    Adiciona um inventário offline de CTAs e formulários incorporados para HTML fornecido, preservando cada ocorrência, com destinos ausentes anuláveis, saída JSON e CSV limitada e cobertura explícita de corpo incompleto.

    #875 (issue no GitHub)
  • AlteradoFuncionaPreservar a classificação de timeout remoto ao ocultar erros de transporte e reproduzir…#866

    Preserva a classificação de timeout remoto ao ocultar erros de transporte, e reproduz com segurança manifestos de proxy direto para verificação direcionada.

    #866 (issue no GitHub)
  • AlteradoFuncionaLer evidências de atribuição do grafo de links SQL retido, preservar atribuição nula…#866

    Lê as evidências de atribuição a partir do grafo de links SQL retido, preserva a atribuição nula explícita na exportação e mantém as verificações de links externos armazenadas em spool durante a retomada.

    #866 (issue no GitHub)
  • AlteradoFuncionaRegenerar catálogos integrados e contratos de relatório; instalar o validador de PDF com#866

    o…

    Regenera catálogos integrados e contratos de relatório; instala o validador de PDF com o extra all e mantém os testes com navegador falso independentes da seleção do Chrome local.

    #866 (issue no GitHub)
  • AdicionadoFuncionaAdicionar um plano de carga offline opcional para BigQuery com tabelas versionadas…#837

    Adiciona um plano de carga offline opcional para BigQuery que expõe tabelas com versão de esquema, requisitos de faturamento e pré-requisitos explícitos de autorização, sem acesso à nuvem.

    #837 (issue no GitHub)
  • AdicionadoFuncionaAdicionar um transporte REST do BigQuery com lista de permissões e jobs de carga em#837

    staging…

    Adiciona um transporte REST do BigQuery com lista de permissões, jobs de carga em staging determinísticos, reconciliação de contagem de linhas e publicação atômica documentada por tabela, em vez de uma transação entre tabelas que não existe.

    #837 (issue no GitHub)
  • AlteradoFuncionaExigir uma aprovação cost_authorized do BigQuery, separada e controlada pelo host…#837

    Exige uma aprovação cost_authorized do BigQuery, separada e controlada pelo host, antes de qualquer token, verificação de dataset ou gravação em staging.

    #837 (issue no GitHub)
  • AdicionadoFuncionaAdicionar um construtor local e validado de link de cópia do Looker Studio para o…#836

    Adiciona um construtor local e validado de link de cópia do Looker Studio para o pacote sintético de cinco páginas de relatórios. Ele exige um ID de relatório original e aliases exatos de fonte do Sheets ou do BigQuery, sem publicar relatório nem inventar um modelo.

    #836 (issue no GitHub)
  • AdicionadoFuncionaAdicionar o fixture sintético de planilhas versionado#836

    (examples/reporting-pack/worksheets/)…

    Adiciona o fixture sintético de planilhas versionado (examples/reporting-pack/worksheets/): um CSV por dataset do BI, mais o manifesto, gerado de forma byte a byte determinística a partir de examples/audit.json e de duas entradas sintéticas de GSC e GA4. Demonstra os estados de zero medido, suprimido ou ausente, somente externo, não chaveável, verificação ignorada, dataset indisponível e quadrante incompleto, e é verificado como reproduzível por scripts/generate_reporting_pack_worksheets.py --check.

    #836 (issue no GitHub)
  • AdicionadoFuncionaAdicionar examples/reporting-pack/SETUP.md: o guia operacional do proprietário para…#836

    Adiciona examples/reporting-pack/SETUP.md: o guia operacional do lado do proprietário para importar as seis planilhas no Google Sheets, conectar os aliases reservados de fontes de dados, montar as cinco páginas do blueprint com os controles declarados e os campos calculados, ativar a permissão de cópia e verificar uma cópia nova. O modelo nativo do Looker Studio continua sendo uma etapa externa autorizada pelo proprietário; nenhum ID de relatório, link ou gravação no Google é incluído.

    #836 (issue no GitHub)
  • AlteradoFuncionaPreservar os nomes de partição, contagens e checksums do pacote BI gerado para que o…#836

    Preserva os nomes de partição, as contagens e os checksums do pacote BI gerado, para que o fixture de planilhas passe na verificação prévia existente do Sheets e nos consumidores de exportação filtrada. Documenta os campos de alias separados da API de Linking e exige verificação de cópia nova pela URL gerada, sem reparo manual das fontes.

    #836 (issue no GitHub)
  • AlteradoFuncionaRejeitar aliases duplicados da API de Linking após normalização de espaços e retornar…#836

    Rejeita aliases duplicados da API de Linking após normalização de espaços e retorna os aliases exatos usados nos parâmetros de URL. Define IDs compartilhados de campos de execução, controles de data de provedores agrupados e gráficos de cobertura que excluem populações sobrepostas. A criação do modelo nativo e a verificação de cópia nova continuam como requisitos externos de aceitação.

    #836 (issue no GitHub)
  • AdicionadoFuncionaAdicionar linhas explícitas de coorte de URL com evidência qualificada aos pacotes BI#835

    locais…

    Adiciona linhas explícitas de coorte de URL com evidência qualificada aos pacotes BI locais, incluindo quadrantes do Search Console e do GA4 seguros para zero medido, apenas para observações completas, compatíveis e um para um.

    #835 (issue no GitHub)
  • AlteradoFuncionaCalcular parcelas observadas de inlinks a partir de páginas de origem únicas no escopo…#835

    Calcula as parcelas observadas de inlinks a partir de páginas de origem únicas no escopo, com extração HTML concluída, preservando as ocorrências repetidas separadamente e rotulando populações parciais.

    #835 (issue no GitHub)
  • AdicionadoFuncionaAdicionar pacotes BI offline tipados e determinísticos para scans e auditorias salvos…#834

    Adiciona pacotes BI offline tipados e determinísticos para scans e auditorias salvos e para evidências de provedores fornecidas, com limites de partição, estados nulos, conservação de linhas e células CSV protegidas contra injeção de fórmulas.

    #834 (issue no GitHub)
  • AlteradoFuncionaPreservar problemas de companions audit.v2 limitados, cruzar até 1.000.000 de URLs…#834

    Preserva os problemas de companions audit.v2 limitados, cruza até 1.000.000 de URLs de scan retidas por meio de um artefato de evidências SQLite durável e transmite esse artefato para o BI sem materializar listas de páginas ou de URLs correspondentes. Isso não entrega um modelo copiável do Looker Studio.

    #834 (issue no GitHub)
  • AlteradoFuncionaProjetar grupos de problemas, candidatos de quadrantes de provedores e fontes de inlink…#834

    Projeta grupos de problemas, candidatos de quadrantes de provedores e fontes de inlink elegíveis por meio de um índice SQLite descartável e limitado. Mantém as dimensões dinâmicas de provedores válidas nas exportações selecionadas e nos planos offline de Sheets e BigQuery, e limita a quantidade de partições e o consumo de disco.

    #834 (issue no GitHub)
  • AlteradoFuncionaPreservar URLs-alvo e mensagens de problemas de auditoria nativa como colunas BI tipadas…#834

    Preserva as URLs-alvo e as mensagens dos problemas de auditoria nativa como colunas BI tipadas, e não apenas dentro do JSON de origem retido, para que seleções exatas de URLs conservem os problemas afetados.

    #834 (issue no GitHub)
  • AdicionadoFuncionaAdicionar scan-fragment-links (seo_scan_fragment_links) e a verificação#827

    BROKEN_BOOKMARK…

    Adiciona scan-fragment-links (seo_scan_fragment_links) e a verificação de auditoria BROKEN_BOOKMARK: cada <a href> com fragmento no HTML ou DOM completo retido é resolvido contra os IDs de elementos e os alvos <a name> do documento de destino, usando o algoritmo WHATWG de rolagem até o fragmento (o fragmento serializado é testado primeiro contra IDs e nomes; depois, o valor decodificado em percentual e UTF-8 é testado contra os dois; + continua sendo um sinal de mais literal; # e #top resolvem para o topo do documento). As representações estática, renderizada e de fragmento legado são avaliadas de forma independente, as regras de redirecionamento e de <base href> são respeitadas, e uma query string diferente significa um documento diferente. Corpos ausentes, truncados, não suportados, com falha ou que esgotaram o orçamento são registrados como ignorados, com o motivo indicado, nunca como links quebrados. Exportações do Screaming Frog e importações legadas indicam que a verificação está indisponível, em vez de afirmar que passou limpa. Os resultados são limitados e paginados de forma determinística (total, returned, offset/limit, next_offset, estado de cobertura), idênticos na CLI, no MCP e no resumo de auditoria do scan retido. Nada é buscado: a avaliação é somente leitura e offline.

    #827 (issue no GitHub)
  • AlteradoFuncionaValidar links de retorno de hreflang nativos contra declarações completas de alvos#825

    retidas…

    Valida links de retorno de hreflang nativos contra declarações completas de alvos retidas, distinguindo um retorno ausente conhecido de um alvo não rastreado ou com corpo indisponível. Informa alternativas observadas com noindex, preserva rótulos brutos e identidades de URL normalizadas com contexto de duplicidade e conflito, e marca relações parciais de população como não medidas. As superfícies existentes de auditoria, CLI, MCP e relatório trazem os mesmos problemas, sem buscar nada adicional.

    #825 (issue no GitHub)
  • AdicionadoFuncionaAdicionar CANONICAL_TARGET_ERROR para informar alvos canônicos buscados com 4xx/5xx…#824

    Adiciona CANONICAL_TARGET_ERROR para informar alvos canônicos buscados que retornam 4xx ou 5xx, com evidências de origem, alvo, resposta e indexabilidade. Alvos desconhecidos ou com status incompleto continuam indisponíveis; variantes 2xx conhecidas removem o veredito de erro, e alvos 3xx permanecem em CANONICAL_TO_REDIRECT.

    #824 (issue no GitHub)
  • AdicionadoFuncionaAdicionar CANONICAL_HOMEPAGE_GROUP para grupos de pelo menos três páginas indexáveis…#824

    Adiciona CANONICAL_HOMEPAGE_GROUP para grupos de pelo menos três páginas buscadas e indexáveis, em dois ou mais trechos de caminho, com títulos e H1s distintos, que apontam canonicamente para a homepage buscada. Autorreferência da home, URLs com query, paginação reconhecível, padrões configurados de paginação ou filtro, evidência incompleta da homepage e rastreamentos nativos parciais não geram problema em nível de site.

    #824 (issue no GitHub)
  • AdicionadoFuncionaAdicionar evidências objetivas de autoria, datas e páginas de confiança às auditorias…#823

    Adiciona evidências objetivas de autoria, datas e páginas de confiança às auditorias de escopo (issue #823): oito verificações de severidade informativa em seohead/sf/core/eeat.py, que relatam o que um crawl pode observar, e nunca uma pontuação de E-E-A-T. NO_AUTHOR_BYLINE e NO_CONTENT_DATES disparam apenas em páginas com cara de conteúdo (um tipo de artigo em JSON-LD, og:type=article, um elemento <article> ou um caminho de conteúdo convencional) e citam os portadores que leem (meta_author, rel_author, itemprop=author, classe byline, <time datetime>, author, datePublished e dateModified do JSON-LD, um caminho de URL com formato de data), cada um com uma confiança declarada. MISSING_ABOUT_PAGE, MISSING_CONTACT_PAGE, MISSING_PRIVACY_POLICY e MISSING_TERMS_PAGE informam um dos estados found_indexable (silencioso), found_non_indexable, found_error, discovered_not_crawled ou not_discovered, para que uma página que existe mas não responde nunca pareça igual a uma que ninguém linkou. FEW_CITATIONS informa apenas o que as posições dos links conseguem comprovar (um link de saída dentro do texto do corpo, ou uma contagem declarada de zero), e YMYL_REVIEW_CANDIDATE sinaliza correspondências determinísticas de palavra inteira em caminho ou título para revisão humana, nunca uma classificação. O não medido permanece distinto do ausente em todo o processo: uma página cujo corpo nunca foi analisado mantém trust_signals como NULL e é contada no motivo do ignorado; summary.trust_evidence registra o escopo avaliado, o estado por tipo de página e uma ressalva de crawl parcial para vereditos not_discovered.

    #823 (issue no GitHub)
  • AlteradoFuncionaClassificar LCP, INP e CLS p75 de campo do CrUX na janela atual contra limites oficiais…#822

    Classifica o p75 de LCP, INP e CLS de campo da janela atual do CrUX contra limites oficiais versionados, mantendo o escopo de URL ou origem, fator de forma e período de coleta. Evidência de campo ausente, incompleta ou com falha permanece indisponível ou parcial.

    #822 (issue no GitHub)
  • AdicionadoFuncionaAdicionar amostragem explícita e limitada de URLs com cache privado opcional e aceitar…#822

    Adiciona amostragem explícita e limitada de URLs com cache privado opcional, e aceita evidências salvas do CrUX em auditorias de sites e relatórios, sem requisições automáticas ao provedor. Limita os bytes de resposta e de cache, e rejeita contagens de amostra salvas inconsistentes ou registros de URL repetidos, em vez de informar cobertura de campo completa.

    #822 (issue no GitHub)
  • AlteradoFuncionaDocumentar o limite atual da CLI Docker de execução única, separado do serviço remoto…#820

    Documenta o limite atual da CLI Docker de execução única separadamente da API remota e do serviço de worker opcionais, construídos explicitamente.

    #820 (issue no GitHub)
  • AdicionadoFuncionaAdicionar a receita de execução SSH em workspace persistente e explicar que o estado…#820

    Adiciona a receita de execução SSH em workspace persistente e explica que o estado de saída e os artefatos da CLI não são uma verificação de saúde de serviço HTTP.

    #820 (issue no GitHub)
  • AlteradoFuncionaAdmitir configurações explícitas de crawl SQLite nativo de até 1.000.000 de URLs…#818

    Admite configurações explícitas de crawl SQLite nativo de até 1.000.000 de URLs, com orçamento separado de 2.000.000 de requisições HTTP e o perfil sintético somente de armazenamento já existente. CLI, MCP, fila remota e workers preservam os mesmos orçamentos declarados. APIs legadas e de lista materializadas mantêm um limite de segurança explícito de 50.000 URLs. Robots da lista, retentativas, saltos de redirecionamento e de canonical agora compartilham o orçamento de requisições. Auditorias nativas e reanálise offline usam o caminho audit.v2 limitado, sem a antiga recusa de ponte de 10.000 páginas ou 20.000 formulários. Contadores do gravador transacional evitam reescanear a fronteira de rastreamento crescente a cada lote. Um driver manual de aceitação registra as identidades das fontes carregadas, a interrupção e a retomada, e os consumidores downstream; a admissão, por si só, não é evidência de aceitação concluída de um milhão de URLs.

    #818 (issue no GitHub)
  • AlteradoFuncionaExecutar cada etapa manual de aceitação nativa sob um watchdog de recursos de subprocesso…#818

    Executa cada etapa manual de aceitação nativa sob um watchdog de recursos de subprocesso, retém artefatos interrompidos, verifica cada linha e a cobertura de tarefas em CSV e XLSX, e testa separadamente o HTTP em loopback próprio e protegido, com o pacing padrão inalterado.

    #818 (issue no GitHub)
  • AlteradoFuncionaPermitir durações de crawl remoto explicitamente autorizadas de até 14 dias…#818

    Permite durações de crawl remoto explicitamente autorizadas de até 14 dias, mantendo o padrão de uma hora e os orçamentos independentes de projeto, requisições, disco, lease e renderização. Isso permite que um alvo de um milhão de páginas caiba em sua taxa de requisições polida e inalterada. Valores acima do teto de duração e tipos inválidos falham antes da coleta.

    #818 (issue no GitHub)
  • AlteradoFuncionaA reanálise offline usa um prazo novo para cada operação de execute e fetch do SQLite,#818

    preservando a interrupção e o cancelamento de consultas sem cobrar o parsing em Python nem as gravações derivadas do prazo original de validação na abertura do scan.

    #818 (issue no GitHub)
  • AlteradoFuncionaO crawl-site --out-dir legado agora mantém evidências em sidecars JSONL…#817

    O crawl-site --out-dir legado agora mantém evidências de páginas, links e formulários em sidecars JSONL somente de anexação durante a coleta e a retomada, em vez de reter listas duplicadas na memória. Checkpoints verificam as contagens dos sidecars, e checkpoints v4 antigos com formulários inline migram sem perder problemas de formulário. A ponte de auditoria existente nomeia seus limites de materialização de páginas, formulários e links, e preserva as evidências coletadas quando uma auditoria fica indisponível. Um relatório anterior é mantido sob um nome de arquivo obsoleto, em vez de ser apresentado como execução atual. A escalada nativa de JavaScript lê os registros de páginas por meio de uma view SQLite re-iterável, em vez de reconstruir todos os objetos de página. A transmissão completa de auditorias grandes continua rastreada em #816 e #817.

    #817 (issue no GitHub)
  • AlteradoFuncionaArmazenar auditorias nativas grandes em companions audit.v2 ordenados, sem descartar…#817

    Armazena auditorias nativas grandes em companions audit.v2 ordenados, em vez de descartar a disponibilidade da auditoria.

    #817 (issue no GitHub)
  • AlteradoFuncionaTransmitir a normalização de auditoria nativa para o seu contexto, sem lista#817

    intermediária de registros.

    #817 (issue no GitHub)
  • CorrigidoFuncionaManter mapas de páginas da auditoria nativa e métricas derivadas por página em um…#817

    Mantém mapas de páginas da auditoria nativa e métricas derivadas por página em um armazenamento de contexto SQLite temporário.

    #817 (issue no GitHub)
  • CorrigidoFuncionaManter problemas nativos em disco até que a agregação ordenada atribua suas identidades#817

    de relatório.

    #817 (issue no GitHub)
  • CorrigidoFuncionaManter grupos nativos de duplicidade e de conteúdo em armazenamento SQLite ordenado#817

    durante a análise.

    #817 (issue no GitHub)
  • AlteradoFuncionaLimitar buscas repetidas de páginas, agrupar a busca de backlinks dos problemas e…#817

    Limita buscas repetidas de páginas, agrupa em lote a busca de backlinks dos problemas e resolve profundidades de descoberta nativa sem reconstruir todas as rotas nem carregar todos os nós no Python. Rotas longas mantêm sua profundidade exata e endpoints truncados explícitos.

    #817 (issue no GitHub)
  • AlteradoFuncionaTransmitir a entrada de páginas nativas retidas e as buscas de inlinks antes da#817

    construção…

    Deriva relações não vazias de corpus e de hreflang por meio de índices em disco, retém coleções completas de evidências no audit.v2 e rotula amostras limitadas de relações com suas contagens exatas de ocorrências.

    #817 (issue no GitHub)
  • AlteradoFuncionaLimitar o cache de páginas por bytes Python decodificados estimados, além da contagem…#817

    Limita o cache de páginas pelos bytes Python decodificados estimados, além da contagem de entradas; páginas grandes sem cache continuam legíveis, e mutações invalidam seu peso antigo no cache. Mantém os rankings de tamanho HTML como pares escalares de URL e tamanho, estáveis, em vez de reter cada modelo completo de página, e evita reter JSON serializado de página em callbacks de mutação.

    #817 (issue no GitHub)
  • AlteradoFuncionaReter apenas fatos escalares de URL, status, indexabilidade, canonical e redirecionamento…#817

    Retém apenas fatos escalares de URL, status, indexabilidade, canonical e redirecionamento ao verificar pares com e sem barra final, e fecha explicitamente as conexões SQLite do adaptador durável e do job remoto.

    #817 (issue no GitHub)
  • AlteradoFuncionaTransmitir contagens de cobertura de corpo indisponível e de charset, reter o estado…#817

    Transmite as contagens de cobertura de corpo indisponível e de charset, retém o estado escalar de seleção da página de confiança em vez das populações candidatas de páginas, e processa as correspondências de DOM do HTML armazenado em duas passagens sobre o índice fixo de arquivos. Preserva a ordem do representante das variantes normalizadas, os exemplos de URL existentes, a cobertura completa das fontes correspondentes e cada problema.

    #817 (issue no GitHub)
  • AlteradoFuncionaValidar o JSONL legado de checkpoints de crawl linha a linha antes de anexar…#817

    Valida o JSONL legado de checkpoints de crawl linha a linha antes de anexar, recusando evidências ausentes, corrompidas ou sem terminador, sem substituí-las. Compara checkpoints de formulários inline mais antigos com o seu sidecar, sem alocar uma segunda lista de formulários.

    #817 (issue no GitHub)
  • AdicionadoFuncionaAdicionar continuação de benchmark de JavaScript com proveniência verificada entre pares…#817

    Adiciona continuação de benchmark de JavaScript com proveniência verificada entre pares concluídos, preservando recibos anteriores e orçamentos de disco. Casos interrompidos permanecem como bloqueios explícitos. Exige consulta e reanálise bem-sucedidas, além de evidência completa em CSV de páginas, antes de marcar um caso de benchmark como aprovado.

    #817 (issue no GitHub)
  • AlteradoFuncionaReter listas explícitas de URLs com o gravador SQLite nativo, preservando a ordem exata…#817

    Retém listas explícitas de URLs com o gravador SQLite nativo, preservando a ordem exata de entrada, vários hosts e a semântica de modo sem descoberta. Transmite a entrada por arquivo de troca, preserva orçamentos de requisições e de tempo durante a retomada da coleta, retém evidências limitadas de resposta e de saltos, e mantém as verificações de grafo e de formulário explicitamente indisponíveis. Listas de diretórios grandes usam o mesmo spool, com uma ponte JSON de auditoria separadamente limitada.

    #817 (issue no GitHub)
  • AdicionadoFuncionaAdicionar companion SQLite audit.v2 versionado para coleções completas de auditoria além#816

    do…

    Adiciona um companion SQLite audit.v2 versionado para coleções ordenadas completas de auditoria além do limite de tamanho do JSON inline, com vinculação de proveniência do scan e validação de integridade de ponta a ponta.

    #816 (issue no GitHub)
  • AlteradoFuncionaTransmitir relatórios audit.v2 em JSON, CSV, XLSX, Markdown e DOCX, comparar populações…#816

    Transmite relatórios audit.v2 em JSON, CSV, XLSX, Markdown e DOCX, compara populações de problemas de alta gravidade e mantém as operações de snapshot e prune pareadas com o companion, preservando o esquema scan.v1.

    #816 (issue no GitHub)
  • AlteradoFuncionaReter associações grandes de grupos ordenados uma única vez no audit.v2 revisão 3 e#816

    ledger…

    Retém associações grandes de grupos ordenados uma única vez no armazenamento audit.v2 (revisão 3) e no ledger (revisão 5), com leituras de audit compatíveis com versões anteriores, migração atômica do ledger, paginação explícita de membros via CLI e MCP, e companions BI de associações completas vinculados à origem.

    #816 (issue no GitHub)
  • AlteradoFuncionaPreservar o digest audit.v2 de origem na reanálise offline; persistir escopo incompleto…#816

    Preserva o digest audit.v2 de origem durante a reanálise offline; persiste o escopo incompleto dos grupos do ledger e fecha os recursos de ingestão em caso de falha na validação.

    #816 (issue no GitHub)
  • AlteradoFuncionaReutilizar o resumo exato de capacidades do corpus enquanto um scan nativo somente…#815

    Reutiliza o resumo exato de capacidades do corpus enquanto um scan nativo somente de metadados não tem evidências de resposta, documento, corpo ou recurso. Assim evita leituras repetidas de todo o corpus a cada commit de página esparsa, sem alterar o armazenamento do scan.

    #815 (issue no GitHub)
  • AdicionadoFuncionaAdiciona um perfilador offline e opcional de capacidade de varredura nativa, com links#815

    dimensionados de forma independente, HTML retido e DOM renderizado, limites explícitos de recursos e um exercício de perda de processo e retomada. Ele reporta o limite existente de admissão de 50.000 URLs e a finalização incompleta como evidência bloqueada, e não como capacidade.

    #815 (issue no GitHub)
  • AlteradoFuncionaNomeia o cancelamento de requisição do navegador fixado como render_cancelled e fecha o#811

    contexto remoto isolado e o navegador em caso de cancelamento ou desconexão, sem fallback local.

    #811 (issue no GitHub)
  • AlteradoFuncionaPermite que a configuração remota confiável do projeto forneça referências de credenciais#810

    de ambiente vinculadas ao host, com proveniência retida e redigida, e falha antes da coleta quando uma referência não estiver disponível.

    #810 (issue no GitHub)
  • AlteradoFuncionaPermite um transporte Playwright remoto, gerenciado pelo serviço e com verificação de#809

    versão, para um projeto em fila, mantendo o endpoint fora dos envios e preservando as requisições de navegador fixadas e sujeitas à política.

    #809 (issue no GitHub)
  • AdicionadoFuncionaExpõe os caminhos observados, os inlinks reversos e o contexto de ocorrência das#807

    varreduras salvas em uma única consulta somente leitura, limitada e compartilhada por CLI e MCP, com identidade explícita da varredura e resultados de erro.

    #807 (issue no GitHub)
  • AdicionadoFuncionaAdiciona posicionamento de links por ocorrência, limitado e somente leitura, e o contexto#806

    do cabeçalho mais próximo, a partir do HTML estático retido e do DOM renderizado, preservando IDs de links duplicados e os estados explícitos de evidência indisponível ou parcial.

    #806 (issue no GitHub)
  • AdicionadoFuncionaNovo comando semantic-inputs (seo_semantic_inputs via MCP) gera o manifesto#801

    reproduzível de entradas normalizadas que o trabalho de similaridade semântica vai consumir: para cada documento, registra o hash do corpo retido, o hash exato da entrada decodificada, o hash da saída normalizada, a estratégia da área de conteúdo e a evidência de idioma (o próprio <html lang> da página e as proporções de letras por script), nunca o texto normalizado em si. --scan faz o streaming de corpos completos retidos, offline, com a configuração de área de conteúdo registrada no rastreamento e sem nova requisição; um corpo ausente ou parcial continua sendo uma omissão explícita, e não um resultado vazio limpo (#801).

    #801 (issue no GitHub)
  • AlteradoFuncionaValida no PDF da auditoria técnica o número de páginas, o tamanho em bytes, o texto#800

    extraível e a conservação dos registros…

    Valida o número de páginas, o tamanho em bytes, o texto extraível e a conservação dos registros do modelo de origem do PDF da auditoria técnica antes que um relatório renderizado seja publicado.

    #800 (issue no GitHub)
  • AdicionadoFuncionaAdiciona saída bilíngue offline em PDF pelo Chromium aos caminhos compartilhados de build#799

    de relatório, em CLI e MCP, validando e higienizando o arquivo temporário antes da substituição atômica.

    #799 (issue no GitHub)
  • AdicionadoFuncionaAdiciona layouts autocontidos de PDF de auditoria técnica em inglês e russo, com tokens#798

    de marca neutros, gráficos de gravidade e cobertura, estados explícitos de execução incompleta e fluxo de páginas para conteúdo longo.

    #798 (issue no GitHub)
  • CorrigidoFuncionaMantém o layout do PDF separado da construção do modelo de auditoria e da integração com#798

    CLI e MCP.

    #798 (issue no GitHub)
  • AdicionadoFuncionaAdiciona um modelo de conteúdo de PDF de auditoria técnica, versionado e offline, que#797

    preserva registros de origem, contagens exatas de origem e projetadas, escopo e estados de cobertura para os dois contratos de auditoria suportados.

    #797 (issue no GitHub)
  • AlteradoFuncionaPersiste versões de cenários de workflow registrados, contexto do site e dos#796

    concorrentes, evidência por etapa e portões de revisão. Execuções interrompidas podem ser retomadas por uma sessão local posterior, mas só depois que as dependências atuais continuarem válidas.

    #796 (issue no GitHub)
  • AlteradoFuncionaExige uma worklist do controlador para iniciar workflows e mantém recibos explícitos de#796

    triagem de notas de especialistas para os resultados de tarefa, meta, concorrente, bloqueado ou rejeitado.

    #796 (issue no GitHub)
  • AlteradoFuncionaExige que os checkpoints de workflow bem-sucedidos verifiquem os bytes dos artefatos#796

    retidos vinculados ao projeto contra seus recibos SHA-256. Evidência ausente ou alterada torna a conclusão anterior desatualizada, sem reescrever o histórico; os orçamentos de verificação nunca certificam evidência silenciosamente nem descartam o recibo dela.

    #796 (issue no GitHub)
  • AlteradoFuncionaPermite perfis explícitos e limitados de política de hash de evidência, normalizando#796

    políticas antigas.

    A observação passiva de workflow verifica os metadados de verificação retidos sem recalcular o hash dos artefatos; recibos alterados ou não verificados continuam explícitos.

    #796 (issue no GitHub)
  • AdicionadoFuncionaAdiciona o comando de CLI project progress, limitado e paginado, e a ferramenta MCP#795

    seo_project_progress, com contagens de estado do checklist e os próximos itens acionáveis. A visão reutiliza os resultados de cobertura no escopo e informa apenas um percentual de conclusão de tarefas de auditoria, explicitamente rotulado, quando cada site incluído tem um plano acordado e um denominador de tarefas medido e não vazio; a cobertura da população de URLs continua separada.

    #795 (issue no GitHub)
  • AlteradoFuncionaOs checklists de projeto agora podem registrar o escopo de auditoria acordado e reportar#794

    razões de cobertura honestas (#794). project-checklist-init / seo_project_checklist_init aceitam um plan opcional: um revisor, uma population de URLs declarada como complete_set, uma sample nomeada ou unknown, com sua source, size ou urls enumeradas, além de templates opcionais com populações por template e um acordo opcional de tasks (all_agreed, ou uma selection de IDs de itens de checklist já existentes). Tudo isso fica vinculado à identidade do site do projeto e carimbado com a revisão de escrita. Registrar um plano atualiza o checklist para seohead.coverage.v3 e acrescenta ao histórico de planos retido; registrar de novo um acordo idêntico é uma operação sem efeito, e um acordo alterado marca as evidências anteriores como desatualizadas, em vez de reavaliá-las com um denominador modificado. Documentos v3 de plano único são migrados na leitura. Ler, reconciliar ou aplicar prioridades nunca atualiza nem inventa uma população, e documentos v1/v2 continuam carregando sem alterações. Itens fora de uma seleção são reportados como not_agreed, visíveis fora de qualquer denominador.

    #794 (issue no GitHub)
  • AlteradoFuncionaA conclusão do checklist agora segue o escopo medido: item automático no escopo do site,#794

    apoiado por medição limitada…

    A conclusão do checklist agora segue o escopo medido: um item automático no escopo do site, apoiado por uma medição limitada (scan parcial), continua pendente em vez de contar como concluído, enquanto um item com escopo em URLs de amostra explícitas ainda é concluído quando o artefato cobre exatamente esse escopo. O campo complete de nível superior agora significa que a auditoria no escopo foi concluída: todas as tarefas acordadas aplicáveis feitas, nenhuma exclusão pendente e a população de URLs acordada totalmente coberta por medições verificadas. Assim, um escopo desconhecido ou não medido nunca pode reportar uma auditoria concluída.

    #794 (issue no GitHub)
  • AlteradoFuncionaO status do checklist agora retorna coverage: cinco razões separadas, audit_tasks,#794

    checks…

    O status do checklist agora retorna coverage, com cinco razões separadas: audit_tasks, checks (com measured_urls), manual_review, deliverable_review e url_population. Cada uma tem seu próprio basis, numerator, denominator e state, para que uma contagem de URLs nunca se misture com uma contagem de verificações ou de tarefas. Um denominador que não pode ser justificado fica null com state: "unknown" e um motivo, em vez de virar 0/0 ou 100%. Medições que não podem ser verificadas contra a população acordada mantêm o eixo de URLs como partial e contam apenas URLs elegíveis verificadas. A pertinência às URLs é verificada contra a enumeração acordada, então uma população declarada apenas por size não conta URLs medidas, e o numerador nunca pode exceder seu denominador. Populações por template são validadas como subpopulações acordadas da população do site quando um plano é registrado ou lido: URLs enumeradas de template devem pertencer ao conjunto de sites enumerado, e a pertinência declarada de template nunca pode exceder o tamanho acordado do site. Um plano incoerente é recusado, em vez de ser cortado ou contado além do denominador. As evidências de verificação salvas agora carregam a enumeração de URLs medidas, de modo que o numerador de URLs é um conjunto auditável, e não uma contagem de linhas. A agregação de vários sites soma os eixos por site e cai para unknown sempre que um site não consegue justificar seu denominador.

    #794 (issue no GitHub)
  • AlteradoFuncionaUm registro not_applicable agora é uma exclusão revisada: exige motivo, revisor…#794

    Um registro not_applicable agora é uma exclusão revisada: exige um motivo, um revisor e uma base de evidência inspecionável, seja um artifact com hash vinculado ao projeto, seja uma referência explícita de evidence. Exclusões revisadas mantêm seu ID estável e seu histórico, saem dos denominadores de tarefas apenas por meio dessa decisão registrada e são listadas separadamente em exclusions. Um item desativado, um registro de exclusão desatualizado ou um registro not_applicable legado, gravado antes da regra de base de evidência, permanece dentro do denominador como pending_exclusion até ser revisado de novo. Assim, desativar, remover do catálogo ou reclassificar nunca reduz silenciosamente as contagens acordadas. Uma exclusão revisada nova em um item removido do catálogo é resolvida normalmente, em vez de ficar pendente para sempre.

    #794 (issue no GitHub)
  • AdicionadoFuncionaAdiciona o prompt endereçável workflow/full-audit-v1 e o cenário full-audit pelas#793

    rotas de catálogo existentes…

    Adiciona o prompt endereçável workflow/full-audit-v1 e o cenário full-audit pelas rotas de catálogo de skill e de cenário já existentes, em CLI e MCP. O workflow reutiliza os caminhos de coleta e de método já entregues, condiciona verificação e relatório à evidência real e separa a preparação do projeto da conclusão da auditoria completa.

    #793 (issue no GitHub)
  • AlteradoFuncionaVincula decisões de remediação a artefatos de verificação imutáveis e a hashes exatos de#792

    evidência antes e depois, incluindo as linhas de base audit.v2 em streaming.

    #792 (issue no GitHub)
  • AlteradoFuncionaReporta resultados de remediação retidos, com estados de cobertura representada e de#791

    escopo completo, denominadores por tarefa e páginas de casos limitadas para ledgers grandes.

    #791 (issue no GitHub)
  • AdicionadoFuncionaAdiciona reverificações de remediação limitadas e indexadas pelo ledger, que reutilizam o#790

    verificador protegido, fazem streaming de seleções audit.v2 e recusam desvio de escopo.

    #790 (issue no GitHub)
  • AlteradoFuncionaVincula a verificação de remediação à identidade da auditoria retida e à política#790

    original que afeta os resultados. Um UUID de varredura reutilizado, sozinho, não consegue mais resolver um caso antigo.

    #790 (issue no GitHub)
  • AdicionadoFuncionaAdiciona o ledger de remediação ledger.v1 (seohead.storage.ledger, id de aplicação#788

    SEOL)…

    Adiciona o ledger de remediação ledger.v1 (seohead.storage.ledger, application id SEOL): um artefato SQLite separado e vinculado ao projeto, que registra achados, identidade por ocorrência, pertinência de URLs afetadas e histórico de observações somente de acréscimo, a partir de auditorias scan.v1/scan.v2 validadas, sem alterar as varreduras de origem. A ingestão vincula cada origem pelo UUID da varredura mais a revisão de evidência, o hash da auditoria e a identidade do produtor e da configuração. Reenvios exatos são idempotentes, e bytes conflitantes sob a mesma revisão são recusados de forma atômica. A cobertura capped/aggregate_only e a evidência unavailable são retidas como dados, e não tratadas silenciosamente como resolvidas. Inclui migração transacional 0→1, validação completa de schema e integridade na abertura, e docs/LEDGER.md (#788).

    #788 (issue no GitHub)
  • AdicionadoFuncionaAdiciona um perfil descartável de proxy reverso TLS em loopback que verifica isolamento#787

    autenticado de artefatos, backup e restauração, expiração e rollback atômico de upgrade, sem implantar nenhum serviço.

    #787 (issue no GitHub)
  • AlteradoFuncionaDocumenta jobs pontuais de CLI via SSH, registros de artefatos/incidentes, recuperação#787

    sintética e o…

    Documenta jobs pontuais de CLI via SSH, registros de artefatos e incidentes, recuperação sintética e o limite separado do futuro serviço: saúde, proxy, TLS e firewall.

    #787 (issue no GitHub)
  • AdicionadoFuncionaAdiciona o perfil de operador de serviço remoto self-hosted, com binds privados, saúde#787

    autenticada…

    Adiciona o perfil de operador de serviço remoto self-hosted, com binds privados, evidência de saúde autenticada, referências de arquivos de segredo, registros de incidentes, restauração consistente com SQLite, rollback de release e expiração explícita de artefatos terminais.

    #787 (issue no GitHub)
  • AdicionadoFuncionaAdiciona uma política de destino remoto vinculada ao projeto para jobs futuros em fila.#786

    Quando vinculada por um worker, valida destinos e configurações, verifica o DNS novamente no despacho, fixa as requisições de recursos HTTP e de navegador e aplica orçamentos de requisições por origem e no total. Proxy remoto e backends alternativos de navegador falham de forma segura, ou seja, são bloqueados, até que a segurança do egress seja comprovada.

    #786 (issue no GitHub)
  • AdicionadoFuncionaAdiciona uma fila SQLite isolada por projeto e um worker de varredura nativa com lease#785

    para a API remota autenticada e opcional. Os jobs retêm varreduras nativas e relatórios em JSON/Markdown, suportam envio idempotente, cancelamento, recuperação de falhas após reinício, downloads de artefatos com escopo e retenção explícita, sem habilitar nenhum listener por padrão.

    #785 (issue no GitHub)
  • AlteradoFuncionaDefine um contrato opcional, autenticado e versionado para a API de varredura remota, com#784

    configurações nativas de rastreamento limitadas, permissões com escopo por projeto, envio idempotente, schema OpenAPI e evidência compatível com o status de varredura. Exige workers duráveis separados e política de destino e egress. Instalações locais de CLI/MCP permanecem inalteradas (#784).

    #784 (issue no GitHub)
  • AdicionadoFuncionaAdiciona um runbook SSH para Ubuntu com versão fixada e um smoke test descartável do#783

    ciclo de vida Linux, que comprova instalação, renderização de JavaScript, descoberta de artefatos, upgrade, evidência de versão e rollback, sem serviço remoto.

    #783 (issue no GitHub)
  • AlteradoFuncionaNormaliza evidências de analytics e busca importadas para joins de varredura (#781).#781

    evidence-normalize lê uma exportação CSV/XLSX/JSON fornecida, ou um envelope salvo seohead.provider-evidence.v1, totalmente offline, e produz um documento versionado seohead.normalized-evidence.v1 com base em um manifesto opcional seohead.evidence-mapping.v1. Mantém a proveniência por campo (envelope, declarado ou desconhecido) para fonte, identidade do relatório, período, fuso horário, atribuição, mecanismo, cobertura de coleta e vínculo de URL. Um 0 medido continua zero, enquanto linhas ausentes, células nulas ou em branco, células de fórmula, valores suprimidos, períodos não coletados e coletas com falha ou ignoradas continuam explicitamente indisponíveis. evidence-join une a evidência normalizada a uma lista de varredura, auditoria ou páginas, sob a política de chave estrita external_join.v1 e apenas com relaxamentos explícitos. Ele preserva as populações com correspondência, só no rastreamento, só externas e não chaveáveis em sua granularidade declarada, e reporta colisões de chave em vez de multiplicar linhas. --compare com uma política declarada acrescenta uma decisão pura de compatível, incompatível ou desconhecido sobre período, fronteira de fuso horário, identidade, atribuição, mecanismo e granularidade, e informa a elegibilidade de quadrantes com zero medido para o trabalho de coorte posterior. Fontes restritas mantêm linhas e identificadores dentro de um artefato local privado e retornam apenas contagens.

    #781 (issue no GitHub)
  • AdicionadoFuncionaAdiciona uma experiência offline de prontidão de provedor, com referências de credencial#780

    redigidas, schemas de rota de operação, metadados de cota e privacidade e estados explícitos de acesso ao alvo. A mera presença de credencial nunca verifica permissão.

    #780 (issue no GitHub)
  • AlteradoFuncionaExpande seohead watch para um observador de projeto somente leitura, com navegação de#775

    achados retidos, detalhe de evidências, estado de visões salvas e de revisão, e avisos de caixa de entrada MCP explicitamente restritos ao escopo.

    #775 (issue no GitHub)
  • AdicionadoFuncionaAdiciona entrega sintética autorizada de relatórios, com recibos de idempotência duráveis#773

    e comportamento de reinício seguro para novas tentativas.

    #773 (issue no GitHub)
  • AlteradoFuncionaPreserva reivindicações de entrega incertas após a saída do processo ou confirmação#773

    malformada de documento…

    Preserva reivindicações de entrega incertas após a saída do processo ou uma confirmação malformada de documento, impedindo um segundo envio automático quando o aceite não puder ser estabelecido.

    #773 (issue no GitHub)
  • AlteradoFuncionaMede prévias de relatórios a partir da evidência retida, incluindo tamanho renderizado,#772

    hash da fonte, contagens de população, cobertura e perfil. Reporta renderizadores ausentes e entradas acima do tamanho máximo antes do envio. Alinha o orçamento de JS do assistente completo ao contrato da fila compartilhada.

    #772 (issue no GitHub)
  • AlteradoFuncionaRetém identidades exatas de despacho confirmado do bot mesmo após falhas de fila e de#771

    posse, deduplica atualizações confiáveis e isola status, cancelamento, recuperação e entrega por ator e chat iniciadores. Reexecuções idênticas e intencionais continuam sendo jobs separados.

    #771 (issue no GitHub)
  • CorrigidoFuncionaRestaura o último job confirmado do ator e chat após reinício do serviço, preservando#771

    cancelamento…

    Restaura o último job confirmado do ator e chat após o reinício do serviço, preservando o cancelamento e o comportamento de nova execução reconfirmada, sem retomar um rascunho não confirmado.

    #771 (issue no GitHub)
  • AdicionadoFuncionaAdiciona o pacote de evidências de revisão de software para autohospedagem, revisão#761

    jurídica e de compras (#761). scripts/generate_review_pack.py gera e verifica um inventário versionado de dependências e licenças (um perfil por grupo de instalação, com versões resolvidas e fontes de licença medidas no ambiente de geração; requisitos excluídos por marcador, não satisfeitos pela especificação ou não instalados são registrados, e não descartados), um documento de proveniência no nível da release, que vincula as distribuições construídas a uma tag e à revisão de origem do manifesto de build embutido, e um SHA256SUMS.txt que cobre tudo isso. A geração recusa uma tag que divirja de pyproject.toml. A verificação revalida formatos e hashes registrados e reextrai cada distribuição para revalidar seu manifesto embutido, o nome e a versão declarados pelo nome do arquivo e os campos Name/Version do próprio *.dist-info/METADATA ou PKG-INFO contra pyproject.toml, em vez de confiar no registro. Uma varredura de sentinela SEOHEAD_REVIEW_CANARY_* comprova que os arquivos do pacote e os diagnósticos não carregam credencial plantada nem marcadores de cliente. A CI regenera e verifica o pacote com uma tag descartável em cada execução. O workflow de release o verifica e o anexa a uma release v* real.

    #761 (issue no GitHub)
  • AdicionadoFuncionaAdiciona docs/SOFTWARE_REVIEW.md: o mapa de endpoints de saída e de fluxo de dados (o#761

    que cada recurso contata, o que envia e se a chamada é opcional), a fronteira local e remota, o armazenamento de credenciais e artefatos, o status de telemetria, a forma de reportar problemas de segurança e o status de manutenção, e como revisar mudanças de release. Ele linka os runbooks de instalação e implantação em vez de duplicá-los (#783, #787).

    #761 (issue no GitHub)
  • AdicionadoFuncionaAdiciona uma verificação prévia offline de capacidade e checksum do Google Sheets para#760

    pacotes BI locais completos. Não faz nenhuma requisição ao Google nem gravação em planilha.

    #760 (issue no GitHub)
  • AdicionadoFuncionaAdiciona um transporte explícito de substituição do Google Sheets, com lista de#760

    permissões e mapeamentos de aba por dataset…

    Adiciona um transporte explícito de substituição do Google Sheets, com lista de permissões, mapeamentos de aba por dataset, staging e leitura de verificação limitados e uma única publicação atômica apenas de valores, que preserva os IDs de aba existentes.

    #760 (issue no GitHub)
  • AlteradoFuncionaRegistra o staging do Google Sheets antes de qualquer criação remota de stage e#760

    reconcilia uma resposta perdida…

    Registra o staging do Google Sheets antes de qualquer criação remota de stage e reconcilia uma resposta de início perdida pelas identidades determinísticas das planilhas de stage antes de tentar novamente.

    #760 (issue no GitHub)
  • AlteradoFuncionaPreserva valores numéricos e booleanos tipados e leituras esparsas do Google, rejeita#760

    alvos de aba duplicados e divergência de contrato de dataset, vincula a recuperação ao alvo exato configurado e retém o staging retomável após esgotamento de cota. Orça o crescimento da grade de destino antes da substituição atômica e reporta contagens de linhas não confirmadas em execuções interrompidas.

    #760 (issue no GitHub)
  • AlteradoFuncionaValida companions de grupo completos e vinculados à origem antes de gravações no destino…#760

    Valida companions de grupo completos e vinculados à origem antes de qualquer gravação no destino, preserva-os junto com os achados selecionados e divulga referências de pertinência apenas locais nos recibos do destino e da pasta de trabalho, sem afirmar que o companion foi enviado.

    #760 (issue no GitHub)
  • AlteradoFuncionaDivide grandes conjuntos de registros XLSX do scan-export em abas numeradas e#759

    determinísticas, com uma aba Partitions de conservação de linhas, em vez de falhar no limite de linhas por aba do Excel.

    #759 (issue no GitHub)
  • AlteradoFuncionaDivide as abas Findings e Pages do report-build no limite de linhas do Excel e emite um#759

    .xlsx.index.json…

    Divide as abas Findings e Pages do report-build no limite de linhas do Excel e emite um .xlsx.index.json com hash, com intervalos exatos de registros, população de origem, referências de seleção e cobertura. Preserva o relatório anterior quando falhas de gravação são capturadas e limpa os spools de streaming em caso de interrupção.

    #759 (issue no GitHub)
  • AlteradoFuncionaRecusa células XLSX acima de 32.767 caracteres antes que a biblioteca de planilhas possa#759

    truncá-las, protege os metadados da aba Summary contra injeção de fórmulas e rejeita linhas de auditoria retidas malformadas antes que uma exportação incompleta possa declarar sucesso. CSV e JSON completos e a política limitada de visão geral em PDF continuam disponíveis.

    #759 (issue no GitHub)
  • AdicionadoFuncionaAdiciona entrega limitada de CSV para BI selecionado, com contabilização exata de linhas#759

    de origem, selecionadas e omitidas…

    Adiciona entrega limitada de CSV selecionado para BI, com contabilização exata de linhas de origem, selecionadas e omitidas, cobertura de origem retida, hashes em streaming e um índice durável de intervalos de CSV para aba XLSX. Células grandes do Excel falham antes de serem truncadas, e a saída interrompida não é marcada como concluída.

    #759 (issue no GitHub)
  • AlteradoFuncionaPreserva linhas completas e imutáveis de cobertura de verificações ao lado das#759

    exportações BI de achados selecionados, incluindo os motivos de verificações ignoradas, e oferece suporte à seleção exata de achados por segmento de escopo de rastreamento retido.

    #759 (issue no GitHub)
  • AdicionadoFuncionaAdiciona diagnósticos offline de rastreamento para varreduras nativas salvas e artefatos#758

    legados de execução, com evidência de decisão limitada, explicações acionáveis, acesso somente leitura via CLI e MCP e um comando e ferramenta separados de exportação redigida e opt-in.

    #758 (issue no GitHub)
  • AdicionadoFuncionaAdiciona visões de achados de projeto versionadas, com filtros fechados e ordenação#757

    sensível à gravidade…

    Adiciona visões de achados de projeto versionadas, com filtros fechados, ordenação sensível à gravidade, projeção de colunas e paginação limitada. Ordenar por gravidade decrescente coloca os achados críticos primeiro; em ordem crescente, a lista vai de aviso até crítico. CLI, MCP, relatórios e a futura navegação no terminal podem reutilizar a mesma visão somente leitura, sem alterar a evidência de origem, a pontuação, as tarefas ou a cobertura.

    #757 (issue no GitHub)
  • AdicionadoFuncionaAdiciona planejamento de monitor local, desativado por padrão, com orçamentos explícitos#756

    de atualização incremental e completa, recusa de sobreposição, reivindicações de recuperação, proveniência imutável das observações, retenção de resultados parciais, alertas deduplicados e avisos de recuperação. O monitor não inicia nenhum timer, rastreamento nem canal de entrega.

    #756 (issue no GitHub)
  • AdicionadoFuncionaAdiciona um adaptador de entrega de serviço injetado e explícito para avisos completos de#756

    monitor retidos.

    Exige um destino autorizado e vinculado ao projeto e um armazenamento durável de recibos. Nenhum transporte, conta, timer ou destino é habilitado por padrão.

    #756 (issue no GitHub)
  • AlteradoFuncionaTorna reivindicações de monitoramento retidas, cobertura, proveniência de cache,#756

    evidência de recuperação derivada e entrega opcional de serviço seguras para reinício.

    #756 (issue no GitHub)
  • AdicionadoFuncionaAdiciona um coletor de monitor pontual, explícito e limitado por lease, com evidência#756

    retida consciente de cache e recibos de entrega somente locais.

    #756 (issue no GitHub)
  • AdicionadoFuncionaAdicionado verify-fixes / seo_verify_fixes para reverificar URLs selecionadas a#755

    partir de IDs de achados salvos…

    Adicionado verify-fixes / seo_verify_fixes para reverificações limitadas de URLs selecionadas, a partir de IDs de achados salvos, de uma visão de verificação ou de uma lista explícita de URLs. A ferramenta reaproveita a política de rastreamento registrada, grava um artefato de verificação separado (sem sobrescrever nada) e um relatório focado, e distingue achados resolvidos, persistentes, alterados e não verificáveis. Uma auditoria “after” existente só pode ser verificada sem acesso à rede quando tiver um UUID de scan próprio e um horário de observação registrado posterior; evidências não medidas ou de todo o site nunca são marcadas como corrigidas.

    #755 (issue no GitHub)
  • AlteradoFuncionaRastreamentos nativos de URL podem filtrar rotas descobertas pela extensão final do#749

    arquivo antes…

    Rastreamentos nativos de URL podem filtrar rotas descobertas pela extensão final do nome do arquivo antes das requisições, e pelo Content-Type real da resposta antes do parsing ou da retenção do corpo. As duas etapas de filtro registram suas decisões e preservam as evidências de links, status, cabeçalhos e redirecionamentos; os metadados de HTML filtrados continuam explicitamente não medidos. Recursos de script e folha de estilo mantêm seleção e orçamento de bytes independentes.

    #749 (issue no GitHub)
  • AlteradoFuncionaQuando o corpo HTML não está disponível, os achados derivados dele agora mantêm cobertura#749

    explícita como ignorada, em vez de tratar os padrões do parser como limpos ou como metadados ausentes observados.

    #749 (issue no GitHub)
  • AdicionadoFuncionaAdiciona exclusões auditáveis, por padrão de URL e aplicadas após a análise, para os#748

    achados.

    Achados suprimidos continuam no JSON da auditoria e nas exportações do report-build, com a regra correspondente e o motivo, enquanto os totais de achados ativos, a pontuação e o backlog de tarefas refletem a política configurada. Os artefatos de scan nativos preservam a política para reanálise offline; a quantidade de regras e o tamanho dos campos são limitados.

    #748 (issue no GitHub)
  • AdicionadoFuncionaAdiciona scan-export (seo_scan_export): uma exportação somente leitura e offline dos#747

    dados de scan, sob o contrato versionado scan_export.v1. Ela lê um artefato SQLite scan.v1 validado ou um audit.json do SF Analyzer e grava CSV (um arquivo por tipo de registro, mais um manifesto), XLSX (pasta de trabalho somente de escrita), um envelope JSON em streaming ou um documento XML documentado. Cada saída traz proveniência, contagens de linhas exportadas, estatísticas da execução e cobertura explícita — incluindo quais verificações rodaram, foram ignoradas, estavam desativadas ou ficaram sem contabilização —, nada disso podendo ser removido pela seleção de campos. --records e --fields oferecem projeção validada entre registros de páginas, links e achados; tipos de registro ou nomes de campo desconhecidos são rejeitados antes de qualquer arquivo de saída ser criado. Valores ausentes permanecem explícitos (null no JSON, state="absent" no XML, \N no CSV/XLSX), em vez de virar zeros fabricados. A saída XML é serialização gerada, com escape UTF-8 correto; ela nunca interpreta XML, DTDs, folhas de estilo ou entidades fornecidas pelo usuário. CSV/XLSX mantêm a defesa existente contra injeção de fórmulas; o XLSX recusa estouros de linha, coluna e texto de célula do Excel em vez de truncar, e qualquer falha de serialização não deixa nenhum artefato parcial plausível.

    #747 (issue no GitHub)
  • AlteradoFuncionacrawl-site ganha verificação opcional e limitada dos destinos externos registrados:#746

    discovery.external.crawl executa uma fase separada depois que a fronteira interna fecha, buscando cada destino de link de saída distinto uma única vez, com orçamentos próprios de external_checks.max_targets/max_hosts/max_requests/max_depth/max_redirects — nunca um percurso recursivo para fora do host. Os resultados (buscado, falhou, bloqueado, ignorado com a regra que recusou) são anexados a external_checks.jsonl no diretório da execução, mantêm a proveniência da página de origem, persistem ao retomar sem reabrir orçamentos já gastos e informam sua cobertura em discovery.external_checks, separada da completude do rastreamento interno. Exige discovery.external.store; é recusado pelo nome na rota SQLite nativa (--scan-out) até que esse coletor ganhe a fase.

    #746 (issue no GitHub)
  • AdicionadoFuncionaAdiciona política explícita e validada de proxy HTTP para o rastreamento nativo em#745

    páginas…

    Adiciona uma política explícita e validada de proxy HTTP de encaminhamento para o rastreamento nativo, nas requisições de página, sitemap, recursos e navegador fixado, com proveniência de rota redigida.

    #745 (issue no GitHub)
  • AlteradoFuncionaA etapa de renderização do rastreador nativo agora expõe o navegador pela configuração…#744

    A etapa de renderização do rastreador nativo agora expõe seu navegador pela configuração, em vez de fixar o Chromium: rendering.browser.engine seleciona chromium (ainda o padrão), firefox ou webkit pelo mesmo caminho protegido do Playwright; um nome desconhecido falha na validação das configurações, e não no lançamento; e um motor solicitado cujo binário não está instalado gera um erro de dependência que indica a correção (playwright install <engine>), em vez de cair silenciosamente no Chromium. A limitação documentada do Firefox é aplicada com honestidade: ele rejeita rendering.browser.mobile_emulation (is_mobile não é suportado ali), enquanto rendering.browser.touch_emulation (has_touch), que é independente, ainda chega ao contexto. Sondagens e renderizações completas compartilham uma única configuração efetiva, então um padrão nunca é escalado por um navegador diferente daquele que produziu a evidência.

    #744 (issue no GitHub)
  • AlteradoFuncionarendering.browser.viewport_width e rendering.browser.viewport_height adicionam#744

    dimensões arbitrárias de viewport ao lado das predefinições desktop/mobile, que continuam definindo o perfil exatamente como antes. O par é tudo ou nada e limitado a 1..16384 px; um par personalizado substitui apenas as dimensões da predefinição — não implica emulação de mobile ou de toque, que continuam sendo flags explícitas definidas pelo operador.

    #744 (issue no GitHub)
  • AlteradoFuncionarendering.browser.page_concurrency limita quantas buscas no navegador podem estar em#744

    andamento durante a escalada, separadamente de speed.concurrency, que continua regulando a cortesia do rastreamento HTTP. O padrão 1 preserva o comportamento sequencial e não cria pool algum; acima de 1, sondagens e renderizações rodam em um pool de workers limitado, enquanto todo veredito, commit e escrita no SQLite permanecem na thread orquestradora, na ordem de submissão. O prazo de renderização, o orçamento de URLs e as políticas amostrada/completa valem mesmo com concorrência; um lote interrompido aguarda as páginas que já começou e nunca agenda novas; e workers interrompidos ou com falha não deixam thread, página, contexto ou navegador ativos após a chamada.

    #744 (issue no GitHub)
  • AlteradoFuncionaO motor selecionado, sua versão realmente informada, o viewport efetivo e a concorrência#744

    de páginas configurada são registrados no manifesto e na impressão digital do rastreamento, e na proveniência do renderizador de cada documento renderizado — inclusive em tentativas que falharam, que registram o que foi solicitado sem inventar uma renderização bem-sucedida. Os dois caminhos de escalada respeitam as configurações: o rastreamento de diretório e o scan nativo em SQLite, em que os candidatos a links renderizados entram na fronteira pela admissão já existente, com deduplicação, quando rendering.rendered_links.crawl está habilitado.

    #744 (issue no GitHub)
  • AdicionadoFuncionaAdiciona verificações opcionais de canonical para padrões de paginação e filtro na#727

    auditoria…

    Adiciona verificações opcionais da política de canonical para padrões configurados de paginação e filtro nos pipelines de auditoria da exportação SF e do rastreamento nativo. Regras de paginação aceitam destinos self, primeira página ou landing; regras de filtro aceitam destinos self ou landing. Políticas ausentes e destinos que não aparecem na evidência do rastreamento continuam não medidos, e as verificações de status de resposta do destino permanecem separadas.

    #727 (issue no GitHub)
  • AdicionadoFuncionaAdiciona arquivos retomáveis de Search Analytics do GSC no histórico SQLite local#718

    compartilhado…

    Adiciona arquivos retomáveis de Search Analytics do GSC no armazenamento SQLite local compartilhado de histórico de provedores, expostos de forma consistente por gsc-archive e seo_gsc_archive. Status offline, preparação explícita, coleta limitada e snapshots verificados compartilham um único núcleo.

    #718 (issue no GitHub)
  • AlteradoFuncionaPreserva a proveniência de provedor/motor e métricas anuláveis, enfileira só intervalos…#718

    Preserva a proveniência de provedor/motor e métricas anuláveis, enfileira apenas os intervalos de disponibilidade ainda não cobertos e registra esperas por cota e novas tentativas limitadas em falhas transitórias.

    #718 (issue no GitHub)
  • AdicionadoFuncionaAdiciona um histórico SQLite local e versionado para GA4, Metrika, consulta/página do GSC#716

    na web…

    Adiciona um único histórico SQLite local e versionado para GA4, Metrika, consulta/página da web no GSC e dados diários do Yandex Webmaster, com substituição atômica de dias e cobertura explícita: solicitado, vazio, parcial, com falha e atrasado.

    #716 (issue no GitHub)
  • AdicionadoFuncionaExpõe sincronização determinística e limitada, status offline e exportação JSON/CSV pela#716

    CLI compartilhada e pelo MCP local, incluindo aditividade de métricas e metadados conservadores de fuso horário. Nenhuma credencial ou dado de provedor é armazenado no repositório.

    #716 (issue no GitHub)
  • AlteradoFuncionaO modo A do SF agora verifica os recursos de exportação solicitados pela CLI instalada e#715

    exige um conjunto completo e recente de exportações antes da análise. A proveniência do perfil completo registra o manifesto de exportação verificado e a leitura da taxa de rastreamento; um limite de taxa explícito falha antes do rastreamento quando sua configuração base está ausente ou é inválida.

    #715 (issue no GitHub)
  • AlteradoFuncionametrika-report (seo_metrika_report) e MetrikaClient.report(): uma recusa da#714

    Reporting API com “Query is too complicated” agora é repetida em fatias por mês-calendário, com backoff de 5–15 s; uma fatia que ainda for recusada é reenviada com accuracy=0.1 amostrado. Somente métricas comprovadamente aditivas em períodos disjuntos (ym:s:visits, ym:s:pageviews) são mescladas — uma consulta de visitantes únicos, percentuais, médias ou métricas não verificáveis é recusada antes da primeira requisição de fatia, em vez de devolver um valor somado que estaria errado. As fatias são mescladas à medida que chegam, sob um único limite global de linhas que também limita os downloads: quando o limite se esgota, as partições restantes nunca são solicitadas e seus intervalos de datas são listados em split.unfetched — uma fatia interrompida no meio lista o próprio intervalo ali, com partial —; total_rows/totals do período inteiro permanecem desconhecidos quando os períodos não consultados os tornam impossíveis de saber, e a janela devolvida é marcada como parcial. Respostas mescladas reaplicam o sort do chamador (dimensões e métricas, ou o padrão da API, a primeira métrica em ordem decrescente), e a janela offset/limit é tirada do conjunto global mesclado. Os campos de amostragem refletem o que a API realmente informou (sampled, pior sample_share), e uma fatia que não os informa deixa o valor do período inteiro desconhecido — null na resposta da CLI/MCP, nunca um false inventado. contains_sensitive_data é o OR entre as fatias; min/max são recalculados sobre as linhas mescladas; células de métrica e totais ausentes ou malformados marcam o corpo como incomplete, em vez de lerem como zero. O bloco split mantém os períodos solicitados e resolvidos, o fuso horário usado e, por fatia, accuracy, tentativas, linhas descartadas e metadados de amostragem; uma partição que falha nomeia os intervalos concluídos e as accuracies esgotadas. Datas relativas (today, NdaysAgo) são resolvidas no timezone da requisição ou no fuso do próprio contador (time_zone_name, senão seu deslocamento em minutos) — nunca na data do host. Um período que não pode ser mapeado para datas (um atalho como month) ainda é repetido e amostrado antes de o erro ser relançado. Um accuracy explícito é respeitado em todas as formas documentadas (low/medium/high/full ou uma fração numérica como "1"): qualquer valor acima da amostra de último recurso mantém o fallback accuracy=0.1, enquanto uma configuração já mais baixa do chamador (low ou uma fração igual ou abaixo dela) é preservada, em vez de ser reamostrada para cima. Toda requisição tentada — inclusive a chamada recusada do intervalo inteiro — chega ao diário de gastos.

    #714 (issue no GitHub)
  • AlteradoFuncionaYandex Webmaster: a operação indexing agora lê o endpoint v4 real /indexing/samples,#713

    em vez do inexistente /search-urls; o novo broken_links_samples lê /links/internal/broken/samples; e a paginação respeita o limite documentado de cada endpoint por página (500 para consultas, 100 para as listas de amostras), em vez de enviar limit=500 em todos os casos (#713).

    #713 (issue no GitHub)
  • AlteradoFuncionaA coleta paginada do Yandex Webmaster agora valida o count documentado de cada página e#713

    o formato da lista — inclusive um count menor que o número de linhas devolvidas —, pede por página no máximo o restante do orçamento de linhas, para que um corte por max_rows nunca leia além e gere um falso complete; expõe returned/truncated para uma única página não paginada, como fatia limitada; informa partial sempre que restarem linhas não lidas; e falha em páginas malformadas, em vez de declarar um resultado vazio como completo (#713).

    #713 (issue no GitHub)
  • AlteradoFuncionaA verificação de renderização agora usa a confiança da plataforma mais uma CA#709

    explicitamente selecionada, reproduz subrequisições POST fixadas e informa falhas de verificação de certificado sem detalhes de transporte.

    #709 (issue no GitHub)
  • AlteradoFuncionaReconhece a falha de verificação TLS do transporte de proxy fixado e verifica a confiança#709

    explícita em CA de fixture, a reprodução de POST, os limites de resposta e a rejeição de alvos privados, por meio de um interceptor CONNECT sintético e próprio, sem alterar a confiança da plataforma.

    #709 (issue no GitHub)

3 de outubro de 2026

5 adicionado8 alterado1 corrigido
  • AdicionadoFuncionaAdiciona crawl-import para pacotes CSV de rastreamento de terceiros com mapeamento#819

    explícito, preservando a identidade da fonte externa, a cobertura por campo, observações duplicadas e dados indisponíveis em third_party_crawl.v1, sem tratar o resultado como um scan nativo nem como uma auditoria SF.

    #819 (issue no GitHub)
  • AdicionadoFuncionaAdiciona um transporte opcional de navegador Playwright remoto com verificação explícita…#808

    Adiciona um transporte opcional de navegador Playwright remoto, com verificação explícita de endpoint e de versão, estados de falha seguros e nenhum fallback para execução local, preservando os padrões de renderização local.

    #808 (issue no GitHub)
  • AdicionadoFuncionaAdiciona consultas Python somente leitura, limitadas e determinísticas, de menor caminho#805

    observado e de inlinks reversos sobre os links retidos no scan, com identidade do registro de scan em cada salto e cobertura explícita de grafo parcial.

    #805 (issue no GitHub)
  • AlteradoFuncionaAlinha a regressão de roteamento de provedores ao contrato corrigido do Arsenkin Wordstat#779

    Alinha a regressão de roteamento de provedores ao contrato corrigido da requisição de frequência do Arsenkin Wordstat (#720, #779).

    #779 (issue no GitHub)
  • AdicionadoFuncionaAdiciona docs/PROVIDERS.md, uma matriz gerada de capacidades de provedores e workflows…#779

    Adiciona docs/PROVIDERS.md, uma matriz gerada de capacidades de provedores e de workflows especialistas (#779, épico #753). Renderizada a partir do registro ao vivo de provedores, somado a um catálogo curado de workflows em seohead/core/provider_matrix.py, via scripts/generate_provider_matrix.py, ela registra, por workflow, os comandos entregues, autenticação, custo/cota, classe de privacidade, limitações e o fallback em CSV por meio de provider-join. Os status distinguem suportado, parcial, não suportado e não verificado; nenhum provedor declarado é rotulado como verificado ao vivo, trabalhos explicitamente não suportados são listados pelo nome, e uma primeira versão em fases é selecionada sem afirmar que todos os serviços estão cobertos. O desvio entre o documento commitado e os registros é detectado por tests/test_docs_drift.py e tests/test_provider_matrix.py.

    #779 (issue no GitHub)
  • CorrigidoFuncionaCorrige keywords-exact / seo_keywords_exact, que nunca conseguia devolver resultado:#720

    a tarefa era criada para uma ferramenta do Arsenkin chamada keywords_frequency, que não existe, então toda chamada respondia 404 WRONG_TOOL. O !W exato agora vai para a ferramenta wordstat com type=1, o array de frases em queries e a região como lista de um único item.

    #720 (issue no GitHub)
  • AlteradoFuncionaSolicita o seletor overal para !W: os valores ws do Arsenkin são operadores#720

    distintos — base é amplo (WS), quoted é a frase entre aspas (“WS”), overal é a forma exata da palavra (!WS), que é o que !W pede, e exact é a forma de ordem estrita ([!WS]).

    #720 (issue no GitHub)
  • AlteradoFuncionaRemove a pontuação que o provedor recusa antes do envio: uma frase com / ou aspas…#720

    Remove a pontuação que o provedor recusa antes do envio: uma única frase contendo / ou aspas fazia o provedor rejeitar o lote inteiro com 422 JSON_VALIDATION_ERROR. As frases reescritas são informadas em cleaned, para que quem chama veja quais foram medidas em outra forma.

    #720 (issue no GitHub)
  • AlteradoFuncionaDevolve frequencies como {phrase: {"base": N, "overal": N}} junto ao payload bruto do#720

    provedor. Uma frase cujo resultado cita apenas outras regiões é omitida e listada em warnings, em vez de pegar emprestados os números de outra região.

    #720 (issue no GitHub)
  • AdicionadoFuncionaAdiciona acesso somente leitura e limitado ao Topvisor pela CLI e pelo handler MCP#719

    compartilhados, com arquivos centrais de credenciais, paginação explícita e nenhuma operação de verificação paga.

    #719 (issue no GitHub)
  • AlteradoFuncionaAlinha o bloco legado sources.gsc do sources-doctor com provider_status.gsc:#717

    ready e o novo campo components passam a vir dos mesmos componentes de credencial (bearer OAuth, concessão durável ou conta de serviço), em vez de apenas do arquivo bearer; assim, uma conta de serviço configurada deixa de aparecer como se o GSC não estivesse configurado. O componente de conta de serviço agora valida o próprio documento JSON (arquivo regular privado, tamanho limitado, tipo service_account, a URI exata de token do Google e os campos obrigatórios), e os dois blocos do doctor informam um enum seguro service_account_status (missing, unsafe_file, too_large, unreadable, malformed_json, unsupported_shape ou configured_unverified). Assim, um arquivo grande demais, ilegível ou malformado continua distinguível de um arquivo configurado mas não verificado, sem expor seu conteúdo.

    #717 (issue no GitHub)
  • AlteradoFuncionaOs artefatos de scan do crawl-site agora registram finished_at e um ciclo finished…#712

    Os artefatos de scan do crawl-site agora registram finished_at e um ciclo de vida finished assim que cada linha aceita da fronteira atinge um estado terminal, inclusive em execuções cuja evidência retida é parcial: crawl_partial já informa observações omitidas, então uma fila esvaziada não aparece mais como captura interrompida em scan-status, scan-list ou no histórico (#712). Uma execução explicitamente interrompida — abortada antes de aceitar trabalho, cancelada ou parada pelo circuito de erros — mantém interrupted e o motivo registrado, mesmo depois que a fila esvazia, inclusive via resume_or_finalize; assim, os caminhos de parada nunca recebem um carimbo de finalização falso.

    #712 (issue no GitHub)
  • AlteradoFuncionaduplicate-check --scan e boilerplate-report --scan agora processam em streaming um#710

    corpus retido, em vez de falhar em sites de tamanho normal: o prazo de abrir e validar o scan é calculado pelo tamanho do artefato, e cada leitura de documento tem prazo próprio; assim, um corpus de 1.500 páginas não termina mais em interrupted. O orçamento de bytes de entrada do corpus mede o que o analisador realmente retém — Markdown extraído para duplicatas e um digest por página para boilerplate — e não o tamanho bruto do HTML. Ao atingir um limite do corpus, a cobertura é informada como parcial, com as contagens exatas de preparados e elegíveis e o limite que interrompeu a leitura (#710).

    #710 (issue no GitHub)
  • AlteradoFuncionareport() e by_time() do Metrika agora rejeitam offset < 1 localmente com#707

    ValueError…

    report() e by_time() do Metrika agora rejeitam offset < 1 localmente, com um ValueError, em vez de repassá-lo à Reporting API, que responde offset=0 com HTTP 400. Novos testes offline fixam o contrato com base 1 em metrika-report, seo_metrika_report e aggregate_report do provider-collect, e verificam que as condições de parada paginadas (total_rows, ROW_CAP) contam as linhas puladas antes de um offset diferente do padrão (#707).

    #707 (issue no GitHub)

2 de outubro de 2026

1 adicionado2 alterado
  • AlteradoFuncionametrika-traffic-pdf no macOS: o Chrome grava o PDF e continua rodando; o navegador é…#731

    metrika-traffic-pdf no macOS: o Chrome grava o PDF e continua rodando; o navegador agora é iniciado sem esperar e encerrado assim que o PDF é verificado.

    #731 (issue no GitHub)
  • AlteradoFuncionaYandex Webmaster: o user_id é resolvido a partir do token; novas operações somente#713

    leitura summary, diagnostics, sqi_history, search_history, query_history, in_search_history, events_history, indexing_history, important_urls, broken_links_history, external_links_history; params para datas e indicadores; paginação das listas de consultas e de amostras de rastreamento (#713).

    #713 (issue no GitHub)
  • AdicionadoFuncionaNova skill técnica traffic-report: um relatório mensal ou anual de tráfego para o

    cliente…

    Nova skill técnica traffic-report: um relatório mensal ou anual para o cliente, a partir do Metrika, do Webmaster e do Search Console (conversões contadas como visitas, verificações de sanidade das metas, produtos, perfil do comprador e regras de slides).

1 de outubro de 2026

1 adicionado1 alterado
  • AdicionadoFuncionaAdiciona metrika-traffic-pdf (seo_metrika_traffic_pdf): um relatório estático de#731

    tráfego em A4 paisagem, no layout de um dashboard analítico, gerado a partir do Yandex Metrika. Coleta e renderização são etapas separadas. A coleta lê a Reporting API (cerca de 40 requisições gratuitas e somente leitura) e produz um único documento seohead.metrika-traffic/1: nove cartões de KPI (usuários, visitas, visualizações de página, páginas por visita, visitas por dia, taxa de rejeição, duração média da visita, parcela de visitantes com duas ou três visitas e parcela de novos visitantes), com variações em relação ao período anterior de mesma duração e às mesmas datas um ano antes; dinâmica diária; janelas de 3, 6 e 12 meses comparadas às janelas anteriores; buscadores, cidades, países, dispositivos, idade, gênero, principais páginas de entrada e frases de busca; e todos os canais de tráfego. A renderização converte esse documento em HTML autocontido, com gráficos SVG inline, e o imprime em PDF por meio de um Chrome, Edge ou Chromium instalado localmente (SEOHEAD_CHROME sobrescreve a descoberta). Marca (nome, cores, pilha de fontes, texto do logotipo) e rótulos em inglês ou russo são entradas; linhas de consultas do Search Console podem ser adicionadas como página opcional. A atribuição usa por padrão a última fonte significativa (ym:s:lastSignTrafficSource e suas dimensões de buscador e frase), que é o que a interface do Metrika informa; as dimensões de último clique diferem dela em alguns por cento e continuam disponíveis como attribution=last_click explícito. Toda requisição envia offset=1, porque a API conta as linhas a partir de 1. Dados ausentes ficam visíveis: cada bloco traz ok, unavailable ou skipped com motivo; uma variação sem linha de base é null, não zero; um navegador ausente deixa o HTML e marca o PDF como ignorado; e arquivos existentes em out_dir só são substituídos com overwrite=true.

    #731 (issue no GitHub)
  • AlteradoFuncionaRelatórios do Metrika começam em offset=1: a Reporting API é baseada em 1 e respondia#707

    com HTTP 400 a todas as requisições enviadas com offset=0 (#707, #728, #729).

    #707 (issue no GitHub)

26 de setembro de 2026

1 adicionado
  • AdicionadoFuncionaAdiciona evidência HEADING_SKIP no rastreamento nativo para saltos de nível em H1–H6…#725

    Adiciona evidência HEADING_SKIP no rastreamento nativo para saltos de nível de H1–H6 na região de conteúdo nomeada. Títulos de cabeçalho, rodapé, navegação, barra lateral e títulos explicitamente ocultos ou em diálogos fechados são excluídos, para que a interface do template não crie uma hierarquia falsa; execuções somente com exportação do Screaming Frog informam a verificação como indisponível.

    #725 (issue no GitHub)

23 de setembro de 2026

1 alterado
  • AlteradoFuncionaAceita arquivos de segredo privados no Windows, onde não existem bits de permissão POSIX,#708

    e adiciona um script de consentimento no navegador que armazena uma concessão somente leitura do Search Console.

    #708 (issue no GitHub)

13 de setembro de 2026

2 adicionado3 alterado2 corrigido
  • AdicionadoFuncionaSuporta gravadores SQLite nativos, histórico, retentativa, snapshots, reanálise e#705

    publicação de projetos no Windows, com travas por intervalo de bytes gerenciadas pelo sistema operacional e verificações portáteis de espaço livre. Preserva o flush de diretório em POSIX; o flush de arquivo no Windows e a publicação atômica continuam disponíveis, sem a garantia de fsync de diretório POSIX. Os fluxos portáteis são testados no CI do Windows e em um runtime Linux isolado.

    #705 (issue no GitHub)
  • CorrigidoFuncionaMantém a varredura de HTML em texto bruto compatível com versões do Python sem a opção…#705

    Mantém a varredura de HTML em texto bruto compatível com versões do Python que não têm a opção de scripting mais recente do HTMLParser, inclusive a distribuição do Python 3.12 para Windows.

    #705 (issue no GitHub)
  • CorrigidoFuncionaCorrige e cita a orientação do Google sobre dados estruturados e Googlebot, incluindo#704

    FAQ/HowTo…

    Corrige e cita a orientação do Google sobre dados estruturados e Googlebot, incluindo a disponibilidade de FAQ/HowTo e as consequências da política de dados estruturados.

    #704 (issue no GitHub)
  • AlteradoFuncionaDescobre sitemaps a partir da raiz do site pelo robots.txt, com fallback para#703

    /sitemap.xml, e informa a expansão de sitemap que falhou por completo como ok: false.

    #703 (issue no GitHub)
  • AlteradoFuncionaPermite retomar o rastreamento nativo após cookies anônimos definidos pelo servidor e#702

    registra a nova sessão sem reter os valores dos cookies; rastreamentos com credenciais ou perfil persistente continuam não retomáveis.

    #702 (issue no GitHub)
  • AlteradoFuncionaPadroniza os caminhos de scan salvos como --scan e o JSON inline como --input; o#701

    --input com caminho de scan e o --json-input legados continuam funcionando por uma versão, com aviso.

    #701 (issue no GitHub)
  • AdicionadoFuncionaAdiciona um reconhecimento explícito, desativado por padrão, para reter evidência anônima#700

    limitada…

    Adiciona um reconhecimento explícito, desativado por padrão, para reter evidências anônimas limitadas com Cache-Control: no-store, mantendo a omissão dos corpos com credenciais.

    #700 (issue no GitHub)

9 de setembro de 2026

10 adicionado9 alterado2 corrigido
  • AdicionadoFuncionaAdiciona prévias offline de prioridade de projeto e aplicação explícita e versionada de#694

    políticas, com base nos fatos de stack salvos, preservando as escolhas do operador, com histórico atômico de políticas e explicações de prioridade coerentes nos relatórios humanos.

    #694 (issue no GitHub)
  • CorrigidoFuncionaCorrige a orientação sobre renderização de JavaScript, canonical, higiene de URLs e#692

    notranslate, sem alterar verificações de runtime nem severidades.

    #692 (issue no GitHub)
  • CorrigidoFuncionaMantém as URLs de sitemap e robots do fixture de documentação na origem loopback efêmera.#690 (issue no GitHub)
  • AdicionadoFuncionaAdiciona cobertura portátil de checklist de projeto com um catálogo derivado da fonte…#686

    Adiciona cobertura portátil de checklist de projeto, com um catálogo empacotado derivado da fonte, templates personalizados reutilizáveis, histórico de definições e evidências, gravações concorrentes otimistas, revisão explícita manual e de entregáveis, e visões offline de pendente, desatualizado e bloqueado, compartilhadas pela CLI, pelo MCP e pelos relatórios humanos vinculados ao projeto.

    #686 (issue no GitHub)
  • AdicionadoFuncionaAdiciona um resumo de status somente leitura do scan nativo para populações da fronteira…#685

    Adiciona um resumo somente leitura do status do scan nativo, para populações da fronteira e resultados HTTP confirmados.

    #685 (issue no GitHub)
  • AdicionadoFuncionaAdiciona workspaces de projeto locais e portáteis com estados explícitos de checklist…#678

    Adiciona workspaces de projeto locais e portáteis, com estados explícitos de checklist pendente e de preparação.

    #678 (issue no GitHub)
  • AdicionadoFuncionaRegistra no repositório a revisão das orientações do Google Search Central: 175 guias#677

    lidos, seus rótulos, exclusões, data do snapshot e as três correções que ela gerou.

    #677 (issue no GitHub)
  • AlteradoFuncionaO crawl-site em modo URL agora grava um scan SQLite nativo à prova de colisão…#676

    O crawl-site em modo URL agora grava, por padrão, um scan SQLite nativo à prova de colisão na pasta scans/ do chamador. --out-dir continua como rota legada explícita para diretório, enquanto a entrada por lista e as configurações de cache live/replay indicam essa rota, em vez de mudar o modo de coleta silenciosamente.

    #676 (issue no GitHub)
  • AlteradoFuncionaBuilds de distribuição limpos agora incorporam proveniência validada do produtor para#675

    scans SQLite nativos quando não há um checkout de código-fonte disponível.

    #675 (issue no GitHub)
  • AlteradoFuncionaSubstitui afirmações não suportadas de perda de sinal no 301 e de ausência de autoridade#671

    no 302…

    Substitui, na skill de auditoria empacotada, as afirmações não suportadas de perda fixa de sinal no 301 e de ausência categórica de autoridade de link no 302 por orientações sobre intenção permanente ou temporária e URL canônica de destino, citando o Google Search Central. Redirecionamentos temporários continuam válidos para mudanças temporárias; um código de status isolado não mede perda de ranqueamento.

    #671 (issue no GitHub)
  • AlteradoFuncionarender-check --viewport mobile agora usa uma única identidade diagnóstica estável de#670

    smartphone nas requisições brutas e nas feitas pelo navegador. Um --user-agent explícito está disponível pela CLI e pelo MCP, e cada comparação, completa ou parcial, registra a identidade efetiva e o tamanho da viewport.

    #670 (issue no GitHub)
  • AdicionadoFuncionaAdiciona entradas --scan somente leitura para análise de corpus duplicado e#669

    boilerplate, com cobertura do corpo retido e proveniência.

    #669 (issue no GitHub)
  • AdicionadoFuncionaAdicionado um catálogo de entradas de comando gerado automaticamente e documentada a#668

    decisão sobre o armazenamento do scan, do cache HTTP e do journal de execuções.

    #668 (issue no GitHub)
  • AlteradoFuncionaRelatórios para o cliente em Markdown, CSV, XLSX, DOCX e de tarefas agora usam títulos de#660

    problemas voltados ao leitor e as evidências salvas de reprodução, em vez de identificadores do registro ou nomes de coletores. Registros históricos sem evidência suficiente declaram essa limitação explicitamente, enquanto os artefatos de auditoria em JSON permanecem inalterados.

    #660 (issue no GitHub)
  • AdicionadoFuncionaAdiciona project-facts para registrar fatos da stack do projeto após a criação,#648

    opcionalmente a partir de uma única passagem explícita de tech-detect que respeita o robots.txt. Decisões inseridas pelo operador ficam acima das evidências detectadas, e uma detecção indisponível ou ambígua fica ausente, com o motivo registrado.

    #648 (issue no GitHub)
  • AlteradoFuncionaColoca o controlador do projeto no início do README e apresenta o Screaming Frog como#648

    segunda passagem…

    Coloca o controlador do projeto no início do README e apresenta o Screaming Frog como uma segunda passagem de conferência cruzada, e não como padrão de paridade.

    #648 (issue no GitHub)
  • AdicionadoFuncionaInclui examples/project-skeleton com uma checklist inicializada e sem resultados, para#648

    que project status nele mostre contagens de cobertura em vez de not_initialized, e valida esse arquivo contra o catálogo atual.

    #648 (issue no GitHub)
  • AdicionadoFuncionaAdiciona contratos de preparação de projeto, evidências de provedores, corpus salvo,#354

    extração limitada, evidências de scan e de workflow/catálogo, com limites explícitos para as evidências retidas e para o progresso.

    #354 (issue no GitHub)
  • AlteradoFuncionaPerfis MCP e wrappers de progresso que preservam metadados exigem o SDK MCP opcional na#354

    versão 1.29 ou posterior.

    #354 (issue no GitHub)
  • AlteradoFuncionaSimplifica o README em torno de fluxos de tarefa, comando e artefato, remove embeds

    visuais desatualizados e contadores promocionais, e mantém links para as referências geradas da superfície atual da interface.

  • AlteradoFuncionaExpande o README com fluxos práticos de entrada até resultado, chamadas equivalentes de

    CLI/MCP e limites precisos sobre o corpus retido, o navegador e os provedores.

8 de setembro de 2026

8 alterado2 corrigido
  • AlteradoFuncionaAlinha a documentação do artefato SQLite ao corpo nativo entregue, ao histórico e aos#666

    contratos de…

    Alinha a documentação do artefato SQLite ao corpo nativo, ao histórico e aos contratos de reanálise offline que já estão no código (#666). A tabela de campos da página tardia agora é verificada contra o mapeamento do importador, para que uma observação antiga em JSONL continue como NULL no SQL, e não vire um valor “limpo” inventado.

    #666 (issue no GitHub)
  • AlteradoFuncionaAuditorias nativas agora marcam como ignoradas as verificações de meta keywords,#659

    canonical secundária, versão HTTP e amphtml quando os campos de origem não foram coletados.

    #659 (issue no GitHub)
  • CorrigidoFuncionaDeixa de ler, na via de renderização JavaScript, um cookie que o próprio site definiu#656

    como credencial do operador, e informa explicitamente quando uma execução descarta DOMs renderizados (#656). Um navegador devolve tudo o que o Set-Cookie do próprio site lhe entregou. Assim, no instante em que uma página definia um cookie de sessão e depois pedia um subrecurso do mesmo origin — um script, uma folha de estilo, uma imagem, a forma comum da web —, o hook de requisição do renderizador lia o Cookie: da rede e guardava o DOM serializado daquela página como omitted/credentialed, numa execução com http.credential_headers = []. Cada renderização cria o próprio contexto de navegador, então a perda é por página, e não cumulativa: toda página que define um cookie perde o próprio DOM, e a execução informa suas páginas, links e contagens de escalonamento exatamente como faria se estivesse completa. O credentials_used de um documento renderizado agora vem apenas daquilo que a execução foi configurada para enviar — http.credential_headers ou um perfil persistente de navegador —, o que crawl/sqlite_render.py::_policy_facts já deriva e entrega ao renderizador; o renderizador monta o próprio cliente de rede sem credencial própria, então a rede não tinha nada a acrescentar. Um rastreamento com credencial configurada continua omitindo esses DOMs sob credentialed, sem alteração, e o valor do cookie continua nunca sendo armazenado.

    #656 (issue no GitHub)
  • AlteradoFuncionaAs contagens de renderização que uma flag partial não consegue expressar agora são#656

    nomeadas.

    rendered_bodies em um resultado de crawl-site informa quantos DOMs renderizados foram retidos e o motivo de cada um que não foi, e a CLI imprime isso junto da linha de conclusão, em vez de deixar tudo a cargo de uma flag de capacidade que diz “partial” tanto para um DOM ausente quanto para todos eles. Uma execução que não descartou nada não imprime nada extra. As contagens são lidas de volta do artefato do scan, então um scan concluído continua respondendo à mesma pergunta depois.

    #656 (issue no GitHub)
  • AlteradoFuncionaColeta og:url em um rastreamento nativo, em vez de marcar todas as páginas como sem#654

    essa tag (#654).

    rules.check_og inclui og:url entre as missing_tags de uma página sempre que o campo estiver vazio, mas o caminho nativo nunca lia essa tag: não havia og_url em PageRecord, nenhuma coluna og_url em scan_v1.sql e nenhum OG:URL na projeção Internal:All que crawl/evidence.py monta. A coluna só existia do lado do Screaming Frog, onde normalize sempre resolveu OG:URL; assim, uma exportação do site enxergava o valor real, e um rastreamento nativo do mesmo site acusava um defeito — um campo não medido apresentado como medido, em toda página de todo rastreamento nativo, independentemente do que a marcação dizia. Agora a tag é lida onde já são lidas as outras três (o parser já devolvia og:url), armazenada em pages.og_url anulável — anulável como qualquer outra coluna adicionada depois, para que um registro gravado antes da coleta continue distinguível de uma página que não declara a tag — e projetada como OG:URL. Este é o lado de coleta da costura cujo lado de leitura o #646 corrigiu. tests/test_open_graph_seam.py ganha um terceiro site de teste, cujas páginas têm Open Graph mas não têm og:title, para que o achado realmente dispare e sua lista possa ser lida: uma página declara og:url e não pode ser apontada como sem ela; a outra não declara e precisa ser apontada. O teste que importa audita as duas páginas duas vezes — uma a partir do rastreamento e outra a partir de uma exportação Internal:All que descreve as mesmas duas páginas — e exige o mesmo veredito. O #646 e o #654 foram ambos casos de dois caminhos discordando sem nenhum teste que os abrangesse.

    #654 (issue no GitHub)
  • CorrigidoFuncionaDeixa de ler um cookie definido pelo site como credencial do operador, e informa quando#647

    uma execução…

    Deixa de ler um cookie definido pelo site como credencial do operador, e informa explicitamente quando uma execução descarta corpos (#647). Um rastreamento compartilha um único cliente HTTP, e esse cliente mantém um cookie jar: no momento em que qualquer resposta trazia Set-Cookie, todas as requisições seguintes saíam com Cookie:, e o gravador do corpus classificava a busca como autenticada. Em um site público com http.credential_headers = [] e credentials_acknowledged = false, isso descartou 33.001 de 40.920 corpos de página, e a execução informou suas páginas e links exatamente como se estivesse completa. Tudo o que é calculado a partir do HTML armazenado nesse rastreamento — detecção de quase-duplicados, profundidade e contagem de nós do DOM, participação de boilerplate, estrutura de títulos no corpo, reanálise offline — passou a cobrir 7.903 páginas, enquanto cada percentual por página no mesmo relatório cobria 40.920: duas populações apresentadas como uma. Uma captura é considerada credenciada quando a execução foi configurada para enviar um cabeçalho de credencial para aquele host, que é a única forma de um cabeçalho sensível chegar a uma requisição montada pelo rastreador — http.headers é recusado pela validação de configuração. Um rastreamento com credencial configurada continua omitindo esses corpos sob credentialed, sem alteração.

    #647 (issue no GitHub)
  • AlteradoFuncionaAs contagens que uma flag partial não consegue expressar agora são nomeadas.#647

    html_bodies em um resultado de crawl-site informa quantos corpos HTML de página buscados foram retidos e o motivo de cada um que não foi, e a CLI imprime isso junto da linha de conclusão, em vez de deixar tudo a cargo de uma flag de capacidade que diz “partial” tanto para um corpo ausente quanto para quatro quintos deles. Uma execução que não descartou nada não imprime nada extra. As listas de cabeçalhos de requisição e resposta redigidas agora mantêm os nomes dos cabeçalhos que a redação removeu, em x-seohead-redacted-headers, nunca os valores: duas respostas cujos corpos foram tratados de forma diferente antes registravam listas de cabeçalhos byte a byte idênticas, então quem lia o artefato não conseguia saber por que um corpo estava ausente.

    #647 (issue no GitHub)
  • AlteradoFuncionaMove as entradas do changelog de CHANGELOG.md para um arquivo por mudança na pasta#638

    changelog.d/…

    Move as entradas do changelog de CHANGELOG.md para um arquivo por mudança em changelog.d/, para que um pull request deixe de conflitar com todos os outros que foram mesclados antes dele (#638). Cada branch adicionava sua entrada no topo de ## Unreleased, o que fazia dessa única linha o ponto de disputa do arquivo: nove resoluções manuais em oito pull requests, em duas sessões, cada uma um re-push e uma nova execução de CI, e a resolução era sempre “manter nosso bloco, depois o deles”. Um conflito cuja resposta nunca varia não traz informação nenhuma, e é uma chance de perder um parágrafo enquanto se pensa em outra coisa. A correção de .gitattributes proposta na issue — CHANGELOG.md merge=union — foi medida e descartada antes disso: o union mescla linha a linha, então, quando as duas entradas contêm uma linha idêntica (uma linha em branco dentro de uma entrada já basta), ele mantém uma cópia e informa sucesso, apagando a linha da outra entrada sem conflito e sem aviso. Um primeiro teste, com linhas deliberadamente distintas, mesclou sem problemas e escondeu isso. Trocar um conflito ruidoso por perda silenciosa de dados é estritamente pior que o conflito, então foi enviada a correção estrutural.

    #638 (issue no GitHub)
  • AlteradoFuncionaUm fragmento recebe o nome da issue que ele fecha (changelog.d/638.md), a chave única#638

    de cada…

    Um fragmento recebe o nome da issue que ele fecha (changelog.d/638.md), a chave que é única para cada branch por construção: um pull request que fecha duas issues gera dois fragmentos, um por issue, e uma mudança que não fecha nenhuma gera no-issue-<slug>.md. Um fragmento contém a entrada exatamente como ela deve aparecer no changelog — um ou mais bullets de primeiro nível com suas linhas de continuação, sem front matter e sem invólucro —, de modo que as entradas em prosa de vários parágrafos que este arquivo traz são preservadas byte a byte, sem serem reformatadas em uma linha. python scripts/build_changelog.py as incorpora em ## Unreleased na hora da release, ordenadas pelo número da issue e não pela ordem que o sistema de arquivos devolver, e --prune remove os fragmentos que foram incorporados. A montagem substitui toda a região entre dois comentários-marcadores, em vez de inserir algo nela, então executá-la duas vezes produz o mesmo arquivo nas duas vezes, tenham ou não os fragmentos sido removidos entre elas. O CHANGELOG.md em si não é regenerado a cada pull request, de propósito: um gate que o mantivesse sempre sincronizado colocaria as duas branches de volta no mesmo arquivo e recriaria o conflito que isto elimina.

    #638 (issue no GitHub)
  • AlteradoFuncionaOs gates de documentação que liam CHANGELOG.md eram o risco, porque um gate que para de#638

    verificar…

    Os gates de documentação que liam CHANGELOG.md eram o risco, porque um gate que deixa de verificar algo em silêncio é pior que os conflitos. Ambos foram encontrados e agora cobrem os fragmentos: tests/test_docs_drift.py tinha CHANGELOG.md em PUBLIC_MARKDOWN, então o gate somente em inglês, o gate de “referencia apenas comandos existentes” e o gate de contagens desatualizadas agora leem também changelog.d/*.md, e os dois gates de deriva de contagem ignoram um fragmento pelo mesmo motivo que ignoram o changelog — uma entrada registra o que era verdade no momento em que foi escrita. tests/test_doc_counts.py exclui deliberadamente o changelog da sua varredura de contagens ao vivo, e sua lista de arquivos nunca chega a changelog.d/, o que dá a mesma resposta pelo mesmo motivo; tests/test_doc_commands.py, tests/test_docs_commands_execute.py e tests/test_examples_gate.py nunca leem o changelog. Um novo tests/test_changelog_fragments.py fixa cada uma dessas respostas, junto com a nomeação de fragmentos, a ordem determinística, a montagem idempotente e o fato de que duas branches concorrentes simuladas, cada uma adicionando um fragmento, se mesclam sem conflito.

    #638 (issue no GitHub)

Anteriores (data não registrada)

23 adicionado30 alterado17 corrigido
  • CorrigidoFuncionaContinua a fazer fingerprinting de uma página cujo site envia um cabeçalho Set-Cookie

    sem valor (#651).

    Um cabeçalho sem nenhum par name=value — Set-Cookie: Secure; HttpOnly, que emall.by envia ao lado de dois cookies bem formados — vira Cookie(name='Secure', value=None) no jar, e httpx.Cookies.__getitem__ levanta KeyError para ele. Por isso, dict(resp.cookies) falhava em um nome que o próprio iterador do mapeamento tinha produzido: tech-detect terminava com código 1, com um error: 'Secure' seco e sem JSON na saída, para uma página que tinha sido buscada com sucesso; o MCP seo_tech_detect propagava o KeyError para quem chamou; e site-audit voltava em silêncio com toda a seção de tecnologias ausente. detect_tech agora percorre o jar de cookies. Um nome sem valor é mantido com valor vazio, em vez de descartado, porque várias assinaturas (BITRIX_SM_GUEST_ID, craft_session, wfvt_) casam apenas pelo nome do cookie, e descartar a entrada perderia esse sinal. Mas ele nunca é normalizado em silêncio como um cookie comum: os nomes são informados em malformed_cookies e citados em um problema, de modo que um cabeçalho que o site enviou quebrado continue sendo um fato sobre o site. Uma resposta só com cookies bem formados não é afetada e informa uma lista vazia.

  • AlteradoFuncionarender-check volta a medir sites compactados em vez de considerá-los quebrados (#650).

    A rota de renderização fixada lia a origem pelo stream não decodificado do httpx e entregava esses bytes ao Playwright junto com o content-encoding da origem. route.fulfill nunca aplica uma codificação de conteúdo ao corpo que recebe, então o Chromium interpretava o gzip como text/html e montava um DOM a partir do fluxo comprimido: sem título, sem h1, sem canonical, sem links, e um tamanho renderizado igual ao tamanho transferido. Todo site que compacta seu HTML — quase todos — voltava com ok: false, reason: incomplete_render, e a mensagem culpava a renderização, sugerindo --wait domcontentloaded ou um --timeout maior, quando a renderização tinha terminado perfeitamente. seohead.tech registrava 22.435 bytes renderizados contra 121.793 brutos; agora registra 123.048, com o título real e 31 links. A rota passa a ler a entidade já decodificada, remove content-encoding do que encaminha (content-length já era removido como hop-by-hop, então o Playwright informa o tamanho do corpo que de fato recebeu) e pede à origem apenas as codificações que este cliente sabe decodificar, em vez de repassar o convite que o próprio Chromium faz para br e zstd. Uma codificação que chegue sem decodificação aborta a requisição e se identifica pelo nome, porque deixá-la passar reproduziria o bug em silêncio. O limite de bytes agora conta bytes decodificados, que é o corpo que o renderizador enxerga — antes, uma bomba de compressão passava pelo limite já comprimida.

  • AlteradoFuncionaLê o Open Graph de um rastreamento nativo pela chave que o parser de fato grava (#646).

    parse_html armazena cada tag pelo nome completo da propriedade — {"og:title": ...}, como diz a própria docstring —, e crawl/collect.py pedia ao mesmo dicionário "title", "description" e "image". dict.get respondia None em todos os casos, então og_title, og_description e og_image ficavam vazios em todas as páginas de todo rastreamento nativo já executado: 0 de 40.920 páginas tinham algum desses valores na execução que revelou o problema, em um site cujas páginas publicam Open Graph. Era a regra central do repositório invertida — um campo não medido lido como medido —, e o problema se propagou, porque crawl/evidence.py projeta essas colunas em OG:Title, OG:Description e OG:Image do quadro Internal:All, então uma verificação via rastreamento nativo via vazio, enquanto via exportação do Screaming Frog do mesmo site via o valor real. O contrato de honestidade de check_og escondeu o dano em vez de mostrá-lo: sem nenhuma coluna OG preenchida em lugar nenhum, a verificação era ignorada, e um site com Open Graph era auditado de forma idêntica a um site sem ele. O parser não mudou; só o lado de leitura foi corrigido. Um novo tests/test_open_graph_seam.py faz o rastreamento de dois sites de teste em loopback e acompanha o valor do parser até pages.jsonl, depois até a tabela pages do artefato de scan e por fim até as colunas OG:* do quadro; rastreia um segundo site sem Open Graph para separar “vazio porque ausente” de “vazio porque não foi lido”; e fixa o formato de chave do parser no mesmo arquivo. A falha era dois módulos corretos discordando sobre o nome de uma chave, sem nenhum teste que abrangesse os dois.

  • AlteradoFuncionaResponde “este site está bem linkado, e onde está linkado mal”, ampliando o registro de

    157 para 161…

    Responde à pergunta “este site está bem linkado, e onde está mal linkado”, ampliando o registro de 157 para 161 verificações e adicionando a skill internal-linking (#634). As peças já existiam — cada aresta com sua posição, âncora e flag nofollow na tabela links, ORPHAN_PAGE, INLINK_BOILERPLATE_ONLY, LOW_LINK_SCORE —, mas nada as transformava em uma resposta sobre o grafo. Uma auditoria de 40.920 páginas trouxe o título errado por horas por causa disso: 66% do sitemap foi reportado como inalcançável por links internos, um número produzido pela subtração da contagem de URLs do rastreamento da contagem do sitemap, o que mede “o rastreador não chegou lá”. Percorrendo as 5.252.235 arestas do próprio artefato a partir da home, a alcançabilidade ficou em 91,9%. O defeito real era a profundidade: 23.742 páginas — 58% do site — estavam a mais de dez cliques da home, e a mais profunda ficava a 3.005, porque o arquivo é uma lista encadeada de links “próximo post” em vez de uma árvore. A profundidade de cliques agora é o título que a auditoria imprime. summary.internal_linking traz o histograma, o máximo, a divisão entre alcançáveis e inalcançáveis, as arestas internas por posição na página e quantas arestas repetem outra aresta, e audit.md apresenta isso ao lado do resumo de saúde. O percurso começa na URL com que o rastreamento de fato começou, nunca em pages.crawl_depth: essa coluna registra onde o rastreador por acaso alcançou uma URL, e um rastreamento semeado pelo sitemap registra 0 para a maior parte do site, então um percurso semeado a partir dela descreveria outro lugar. Quando nenhuma URL inicial foi registrada e mais de uma página declara profundidade 0, a medição se recusa a rodar e informa quais são.

  • AlteradoFuncionaQuatro verificações leem esses números.

    DEEP_CLICK_DEPTH dispara em uma página indexável cujo caminho mais curto a partir da URL inicial excede thresholds.click_depth_max (padrão 10, e cada problema informa o número que usou). DUPLICATE_INTERNAL_LINK dispara em uma página que escreve o mesmo destino e a mesma âncora mais de uma vez: no site acima, 509.744 de 1.134.307 arestas — 44,9% — eram repetições, e se tratava de um mesmo cabeçalho emitido duas vezes, com a segunda cópia removida por JavaScript, um defeito de template que exigiu um script escrito à mão para ser encontrado. LINK_INSIDE_HEADING e IMAGE_LINK_WITHOUT_TEXT precisam do que a região da página de um link não consegue informar — a cadeia de ancestrais da própria âncora e o seu conteúdo —, então um rastreamento nativo agora registra um link_placement_json pequeno e limitado por página, ao lado do esquema de títulos, e ambas as verificações são ignoradas pelo nome em uma exportação do Screaming Frog, em vez de rodar sem ter o que analisar.

  • AlteradoFuncionaAs regras de honestidade que o restante do analisador mantém valem em todo o conjunto.

    Uma aresta sem posição registrada é contada como unclassified e nunca é somada a content: link_position.classify vem desligado por padrão, o que deixa isso em todas as arestas, e uma execução nesse estado deve ser lida como “ninguém olhou”, e não como um site cujos links são todos texto do corpo. Uma posição ausente da distribuição é informada como “nenhuma aresta classificada aqui”, e não como uma região que o site não tem — as regras são testadas em ordem, e um menu dentro de <header> casa primeiro com nav. Um rastreamento parcial retira o veredito de profundidade de cliques esteja ou não disparado, porque uma fronteira nunca buscada pode conter o caminho mais curto; uma verificação que não encontra nada em silêncio seria lida como “todas as páginas estão dentro do limite”.

  • CorrigidoFuncionaDeixa de reportar como limpa uma verificação condicionada a um requisito quando ela nunca

    foi avaliada (#635).

    H2_MISSING só dispara quando uma configuração define requirements.require_h2, e o padrão é false, então em uma execução comum esse ramo é inalcançável. Não deixava nenhum rastro disso: a cobertura contava a verificação entre as silenciosas — o balde que significa “rodou em todas as páginas e não encontrou nada” — e o leitor era informado de que o site tinha passado em uma verificação que ninguém executou. Na auditoria que revelou o problema, 61% das páginas do site não tinham nenhum H2, e 5.066 delas tinham mais de 800 palavras, então a verificação teria disparado milhares de vezes. Agora ela é declarada ignorada pelo nome, com um motivo que cita a configuração que a desligou, de modo que a resposta seja “não avaliada, e eis como avaliar”, e não silêncio. require_canonical tem a mesma forma e recebe o mesmo tratamento; seu padrão é true, então não estava produzindo uma leitura errada ainda, mas agora não pode começar a produzir.

  • CorrigidoFuncionaCorrige o cabeçalho da lista de tarefas que mostrava “Audit Tasks — None” em qualquer

    auditoria sem projeto (#640).

    Corrige o cabeçalho da lista de tarefas que mostrava “Audit Tasks — None” em qualquer auditoria cuja execução não tenha registrado um projeto (#640). render_tasks_md montava o cabeçalho com src.get("project", "site"), mas "project" é sempre uma chave presente no bloco source da lista — ela é definida na montagem a partir de run.get("project"), então uma execução sem projeto grava ali o valor None em vez de deixar a chave ausente, e o padrão do dict.get só vale para chave ausente, nunca para uma que contém None. Um rastreamento nativo e uma reanálise deixam project sem valor, então toda lista montada a partir de qualquer um dos dois recebia a palavra literal “None” como título. O cabeçalho agora usa or como fallback, o que captura um None armazenado, e recorre à start_url ou ao source do site antes de desistir — a mesma ordem que seohead.reports.facts.crawl_domain já usava para resolver o nome de um site a partir do seu bloco run; essa função agora é exportada e reutilizada aqui, em vez de reinventada, de modo que uma lista montada a partir de uma auditoria sem projeto nomeie o site real, e não a palavra “site”. seohead.reports._normalize_sf_audit tinha a mesma forma latente uma linha ao lado (run.get("project") or "", em reports/__init__.py) — já protegida contra um None armazenado, mas seu fallback era um domínio vazio em vez da URL que a execução também conhece, então o cabeçalho “SEO Audit: ” dos docx/md que ela alimenta ficava em branco nas mesmas situações. Agora ele usa a mesma resolução de crawl_domain como fallback.

  • AlteradoFuncionaLê o esquema de títulos como sequência e como mapa da página, ampliando o registro de 155

    para 157 verificações (#632). As oito verificações de título existentes julgam os títulos como um conjunto: podem afirmar que uma página tem um H1 e quatro H2, e nada além disso. Assim, uma página cuja ordem no DOM é H2, H2, ..., H1, H2 passava em todas elas, e também passava uma página cujos H2 eram todos rótulos de menu no cabeçalho — encontrado em um site no ar como um template de artigo com dezoito títulos antes do próprio H1, e reportado como limpo em títulos. O que faltava era a evidência, não a regra: pages guardava h1, h1_2 e h2 — três strings sem ordem nem lugar. Um rastreamento nativo agora registra o esquema completo h1-h6 em ordem de DOM, cada título com seu nível, texto e região da página, em uma nova coluna anulável heading_outline_json, e HEADING_BEFORE_H1 e HEADING_IN_PAGE_CHROME o leem. A região reutiliza a taxonomia que a classificação de links já usa (nav, header, sidebar, footer, content, other), de modo que “no cabeçalho” signifique a mesma coisa sobre um título que já significa sobre um link. Um título que nenhuma regra de posição casou só é posicionado em relação à área de conteúdo quando o documento nomeou uma — um <main>, um [role=main], um <article> ou um seletor configurado; quando a raiz de conteúdo recai no <body> inteiro, chamar um título de “conteúdo” não significaria mais do que “algum lugar da página”, então a região é registrada como não medida e a página entra nas verificações ignoradas da execução com esse motivo, sem ser aprovada como limpa nem marcada como defeito. A ordem não precisa de região, então HEADING_BEFORE_H1 continua respondendo para essas páginas. Uma exportação do Screaming Frog não traz esquema nenhum, e as duas verificações são ignoradas pelo nome ali.

  • CorrigidoFuncionaMantém uma coleta concluída quando a auditoria que vem depois dela falha (#627).

    Um rastreamento nativo de um site no ar passou vinte minutos reunindo 600 páginas em um artefato --scan-out e depois imprimiu error: 'rel_next_2' — o str() de um KeyError é só a chave, e nada além. Sem fase, sem traceback e sem nenhum sinal de que todas as páginas coletadas estavam completas e prontas para reanálise no arquivo. A coleta grava suas linhas e fecha antes de a auditoria começar, então qualquer exceção levantada depois desse ponto é um comportamento errado do analisador, nunca do rastreamento; uma exceção inesperada nessa etapa agora é nomeada pela fase, traz o tipo da exceção além da mensagem e aponta para o artefato retido e para o comando que o reanalisa, exatamente como o caminho de auditoria grande já fazia. A execução informa audit_available: false com esse motivo, em vez de sair com a exceção, e crawl-site termina com código 2 nesse caso — a mesma terceira resposta que a contradição do log-scan já usa, porque 0 leria como “a auditoria rodou e encontrou isto” e 1 como “o comando não produziu nada”, e nenhuma das duas coisas é verdade para um rastreamento cujas evidências sobreviveram. O próprio KeyError não se reproduziu: o mesmo comando contra o mesmo site na main atual foi concluído, então isso muda o que acontece quando uma auditoria falha, não o que causou aquela falha.

  • CorrigidoFuncionaDeixa de perder a auditoria de um rastreamento concluído por causa de um orçamento fixo

    de 30 segundos de inspeção ao reabri-lo (#631). NativeScan.open() lê o cabeçalho de um scan nativo por meio de inspect(), que também executa PRAGMA quick_check e PRAGMA foreign_key_check sobre o banco inteiro — uma verificação de segurança real, mas cujo custo cresce com o tamanho do artefato, enquanto o orçamento não crescia. Um rastreamento de 3,5 horas e 40.920 páginas terminou de coletar tudo o que se propôs a coletar e depois não produziu auditoria nenhuma, porque reabrir o artefato resultante de 1 GB exigia cerca de 48 segundos de validação contra um orçamento fixo em 30. Pior: a falha não dava nenhum motivo para suspeitar de orçamento — o aborto por prazo chega do SQLite como um sqlite3.OperationalError("interrupted") seco, e isso era embrulhado tal e qual em cannot inspect native scan: interrupted, indistinguível de um arquivo realmente corrompido. Os dois problemas foram corrigidos. O orçamento padrão agora é derivado do tamanho do artefato (um piso de 30 segundos para arquivos pequenos, mais uma folga generosa por byte, bem abaixo da taxa de validação medida de cerca de 22 MB/s, já que isso é um teto contra uma leitura travada, e não uma meta de desempenho) — um timeout_seconds explícito de quem chama continua prevalecendo. E um aborto por prazo agora levanta um ScanError que informa o orçamento, o tempo decorrido e o tamanho do artefato, para que um operador consiga distinguir um arquivo grande e lento de um arquivo corrompido, em vez de ler “interrupted” como algo que ele fez errado.

  • AdicionadoFuncionaAdiciona crawl-site --resume <scan.sqlite> (#619).

    NativeScan.resume_snapshot(), a tabela resume_state e o gravador que a preenche já existiam desde que o artefato de scan foi projetado, e crawl_to_scan já continuava um arquivo existente — mas só para quem reproduzisse byte a byte as configurações efetivas originais, e nenhuma interface expunha isso. Apontar --scan-out para um artefato interrompido com qualquer flag alterada era recusado como incompatibilidade de configuração, então, na prática, um rastreamento interrompido (6.516 de 34.635 páginas, em um site de terceiros) tinha de começar do zero. --resume recebe apenas o artefato: a URL inicial e a configuração efetiva completa são lidas de volta do arquivo, porque são o que a fronteira armazenada foi construída com, e qualquer outra flag que molda o rastreamento passada junto é recusada em vez de aplicada. Um scan gravado por outra versão do produtor, registrado para outra URL inicial, já concluído, derivado de uma reanálise ou executado com cabeçalhos de credencial que só consegue guardar redigidos é recusado pelo nome só a partir do arquivo, antes que uma única requisição seja disparada. crawl-site também passa a imprimir uma linha no stderr ao sair, dizendo se o rastreamento terminou ou parou antes, por qual motivo e como continuá-lo — exceto após um orçamento de URLs ou de duração, que uma retomada também lê de volta e portanto não pode repassar; nesse caso a linha diz isso, em vez de oferecer um comando que não faz nada. run.crawl_resumed continua sendo o registro durável: um rastreamento retomado do site de teste offline busca cada URL exatamente uma vez entre os dois processos e produz uma auditoria idêntica à de um rastreamento sem interrupção em todos os campos, exceto naquele.

  • CorrigidoFuncionaImpede que render-check declare uma página não renderizada como limpa, e que descarte

    evidências de HTML bruto (#642).

    Dois efeitos da guarda de #623, ambos em render.py, afetam render-check. Primeiro, uma renderização que estourou o tempo no marco de carregamento recorre a ler o DOM em domcontentloaded — correto em si —, mas, quando nenhum script tinha rodado até ali, o DOM renderizado era igual ao HTML bruto, o comparador não encontrava nada e a execução informava ok: True, js_dependent: False e o único problema “Raw HTML and rendered DOM are materially equivalent; JavaScript rendering does not determine SEO-visible content”, classificado como aviso, sobre uma página que ninguém tinha renderizado. wait_reached registrava a verdade, mas o relatório da auditoria de site carrega para o relatório apenas o texto dos problemas, então a verdade nunca chegava. Uma execução que recorreu a um marco anterior agora diz isso na própria lista de problemas, retém o atestado de ausência de falhas e informa js_dependent: None — esta execução não sabe —, em vez de False. Isso acontecia com o padrão --wait load, e não apenas com networkidle pedido explicitamente. Segundo, a guarda devolvia sua única afirmação “a comparação está indisponível” antes de chegar ao ramo de casca vazia, e o retorno antecipado de render_check omitia a chave empty_shell por completo — então um ponto de montagem vazio de aplicação de página única, que detect_empty_shell() lê da resposta bruta do servidor e que não precisa de navegador algum, era descartado junto com a renderização que falhou. Como uma casca de SPA é exatamente a página cuja renderização estoura o tempo, o problema se perdia justamente onde mais importava. Um problema derivado da metade bruta agora sobrevive a uma renderização inacabada; só os derivados da metade renderizada são suprimidos. Em um rastreamento, uma sonda de renderização que não chegou a um veredito agora vai para patterns_unprobed com seu motivo (canal de #626), em vez de contar como um padrão medido e considerado sem necessidade de renderização.

  • AlteradoFuncionaInforma um robots.txt ilegível como fato sobre o site, não como erro interno (#629).

    EMPTY_ROBOTS — o substituto que _fetch_robots devolvia em todos os caminhos em que o robots.txt não podia ser lido — ainda tinha o formato de robots já analisado, anterior ao parser ganhar grupos e sitemaps. O caminho de sucesso devolve o formato de parse_robots, e esse é o único formato que o contexto robots_summary do artefato de scan aceita; assim, no modo --scan-out, um rastreamento era abortado com native parsed robots summary is invalid sempre que o robots.txt estava inacessível, respondia 429 ou 5xx, redirecionava para fora do host, entrava em loop, passava do limite de saltos ou devolvia um corpo que não era text/plain — ou quando era um 404 simples, que não é erro nenhum, mas o caso “sem restrições” da RFC 9309 e o mais comum dos sete. As duas saídas documentadas se perdiam atrás daquela única linha: um robots.txt ausente agora permite o rastreamento sem restrições novamente, e um robots.txt indisponível interrompe a execução com a nota dizendo qual das seis formas de falha ocorreu. O modo de diretório legado nunca notou o problema, porque nada lê as chaves antigas. Encontrado em um site no ar cujo robots.txt redireciona com 302 para um endpoint de sincronização de cookies, para qualquer user agent que não reconhece.

  • CorrigidoFuncionaCorrige escalate(), que contava uma sonda de renderização falha como “não precisa de

    renderização” (#626).

    Corrige escalate(), que contava uma sonda de renderização falha como “este padrão não precisa de renderização” (#626). Ele amostra uma URL por padrão de template para decidir se aquele padrão precisa de uma busca mais completa, renderizada com JavaScript, mas, quando todas as amostras de um padrão falhavam ao sondar — um erro ao iniciar o navegador, um timeout ou uma renderização incompleta, os modos de falha comuns de um rastreamento real —, o for/else ainda registrava o padrão como sondado, e ele acabava nem escalonado nem listado entre os padrões que a execução não conseguiu avaliar. Isso invertia a regra central do projeto: evidência ausente ou não medida nunca pode parecer limpa. Um padrão sobre o qual nada se aprendeu era rastreado de forma estática em silêncio e reportado do mesmo jeito que um padrão realmente medido e considerado sem necessidade de renderização. EscalationResult agora informa esse padrão em patterns_unprobed, junto dos padrões cortados por prazo que já eram rastreados ali, e registra o motivo de falha da própria sonda no novo patterns_unprobed_reasons, para que um relatório possa dizer “este padrão não foi avaliado” em vez de sugerir que foi. Um padrão com pelo menos uma sonda bem-sucedida não é afetado: isso muda apenas o que acontece quando todas as sondas de um padrão voltam com ok: False.

  • CorrigidoFuncionaImpede que render-check informe uma renderização inacabada como defeito do site (#623).

    Quando a renderização não se completava, o snapshot renderizado voltava sem título, sem h1, sem canonical, com zero links e com um quinto dos bytes da resposta bruta — e o comparador lia essa vacuidade como evidência sobre o site, emitindo “the title changes after JavaScript” sobre um título que a renderização nunca leu e “the canonical is injected by JavaScript” sobre um canonical que nunca viu. Em uma auditoria ao vivo, isso gerou quatro problemas errados e confiantes em sequência, do tipo que manda um desenvolvedor caçar um bug de JavaScript que não existe. Agora o par é avaliado antes de ser comparado: quando a resposta bruta traz marcos estruturais e o documento renderizado não traz nenhum deles, com um tamanho que é uma fração do bruto, a verificação retorna ok: false com reason: "incomplete_render", um motivo nomeado que traz os dois tamanhos em bytes e os dois snapshots para inspeção — sem problemas, e com js_dependent: null em vez de false, porque a execução não sabe. site-audit registra isso em summary.tools_failed, onde pertence uma verificação não medida. A detecção é deliberadamente estreita: um único marco sobrevivente, ou um documento renderizado com pelo menos metade do tamanho da resposta bruta, é comparado como antes, e uma página sem título e sem links dos dois lados é medida e apenas vazia, não marcada como não medida. Um título que um script realmente reescreve continua disparando seu problema. A estratégia de espera também lida com a causa comum: um site cujos scripts de analytics, chat ou anúncios com long-polling nunca deixam a rede ficar ociosa estourava o tempo da verificação inteira sob --wait networkidle, e agora recorre a ler o DOM em domcontentloaded — sem uma segunda navegação —, com uma breve espera para scripts adiados, e wait_reached registra de qual marco o snapshot realmente veio. Uma página cujo DOMContentLoaded nunca disparou continua sendo uma falha de renderização, não uma renderização incompleta.

  • AlteradoFuncionaDá ao crawl-site uma linha de progresso ao vivo (#619, metade de progresso).

    Um rastreamento nativo imprimia sua taxa efetiva de requisições e depois nada até terminar; em um site de 34.000 páginas, a única forma de saber que ainda estava trabalhando era ver o arquivo de scan crescer no ls -la. Agora a linha se atualiza no lugar em um TTY, com páginas buscadas, URLs conhecidas até o momento, o percentual desse conjunto, a taxa atual de requisições numa janela móvel, o tempo decorrido e o tamanho do artefato de scan quando --scan-out está gravando um. O que ela deliberadamente não faz é sugerir um total que não pode conhecer: um rastreador descobre a própria carga de trabalho, então o denominador é fetched + queued, limitado ao orçamento de URLs, é rotulado como known e não como total, e uma linha de cabeçalho impressa uma vez informa que a fronteira ainda está crescendo e que o percentual não é uma estimativa de quando a execução vai terminar. Uma taxa não mensurável aparece como rate n/a, nunca como 0.0 req/s. Os dois números vêm das estruturas do próprio rastreamento — para um scan SQLite, da mesma consulta resume_snapshot que o laço de coleta usa como guia —, de modo que o que aparece na tela é o que o artefato contém naquele instante, e não um contador paralelo que possa se desencontrar dele. Uma saída não interativa (um pipe, um arquivo de log, CI) recebe uma linha simples a cada 30 segundos, em vez de redesenhos com retorno de carro, e um novo -q/--quiet silencia tanto a linha de progresso quanto a linha de taxa de inicialização, deixando intacto o resultado JSON na saída padrão.

  • AlteradoFuncionaFecha as três linhas de paginação que #385 deixou abertas, levando o registro de 152 para

    155 verificações. PAGINATION_MULTIPLE e PAGINATION_URL_NOT_IN_ANCHOR reportam uma página que declara dois sucessores diferentes, ou uma cuja URL declarada não é também uma âncora na mesma página. Os sucessores são comparados depois da normalização de URL — a mesma identidade que a metade de âncoras usa —, então /blog/page/2 e /blog/page/2/ vindos de dois plugins são um só sucessor escrito de duas formas, e não uma série ambígua. PAGINATION_URL_NOT_IN_ANCHOR precisa do inventário completo de links da página e lê a exportação All Inlinks para isso; PAGINATION_MULTIPLE não precisa, e agora lê primeiro as colunas mais leves de ocorrência rel="next" 2 / rel="prev" 2 do Internal:All, do mesmo jeito que CANONICAL_MULTIPLE já responde a partir de Canonical Link Element 2 — All Inlinks é só um fallback para um perfil cujo Internal:All foi gravado sem essas colunas. PAGINATION_SEQUENCE_ERROR reporta uma quebra em uma sequência de números de página que a série de outra forma segue, conforme a ressalva da própria issue: uma série pode começar em um número diferente de um, um passo não é uma quebra, e uma série cujas URLs não declaram número de página é marcada como não avaliada, em vez de julgada contra uma numeração que teria de ser inventada. Toda série que ficou sem julgamento é listada entre as verificações ignoradas da execução, com o motivo verdadeiro *para aquela série* — um passo, um ciclo, uma série curta demais para conter uma sequência e um número de página ilegível são quatro afirmações diferentes, e três delas descrevem séries cujas URLs declaram todas o seu número. A contagem é por série, não por execução, então o formato usual do WordPress (a página um em /blog/ sem número, e as demais em /blog/page/N/) não pode desaparecer atrás de uma série julgável em outro ponto do mesmo rastreamento.

  • AdicionadoFuncionaAdiciona um gate de cobertura de veredito (#98): test_check_producer_gate.py provava

    que cada ID…

    Adiciona um gate de cobertura de veredito de verificações (#98): test_check_producer_gate.py provava que cada ID de verificação estava registrado e que cada função check_* era despachada, mas não dizia nada sobre se a conclusão de uma verificação chegou a ser provada verdadeira diante de um marcado que de fato tem o defeito, nem sobre o marcado que não tem — exatamente a lacuna que deixou #94, #95 e #96 passarem por todos os testes existentes enquanto ainda disparavam errado em sites no ar. test_check_verdict_coverage.py varre tests/ de forma estrutural (AST, não uma lista fixa de chamadas) em busca das duas metades por verificação, e reprova o build para qualquer verificação recém-adicionada ao registro sem um teste dos dois lados ou uma isenção nomeada e fundamentada. Das 152 verificações do registro, 88 já tinham prova dos dois lados; um novo test_check_verdict_gaps.py fecha mais 22 lacunas de baixo custo para teste que a varredura revelou (tamanho e duplicação de title e description, H1 duplicado, presença de H2, higiene de URL, verificações de diretivas e marcação, códigos de resposta e as duas verificações de exportações filtradas nativas). As 64 restantes são nomeadas, não escondidas, na lista de catraca KNOWN_UNCOVERED do gate — essa lista deve diminuir à medida que a cobertura chega, e nunca pode crescer para admitir uma verificação adicionada depois que o gate existia.

  • CorrigidoFuncionaCorrige um defeito na seleção de grupos do robots.txt que deixava um User-agent em

    branco anular a política padrão (#566).

    Corrige um defeito na seleção de grupos do robots.txt que deixava um valor User-agent em branco anular a política padrão de um site (#566). Uma linha User-agent: sem nada, ou uma cujo nome de bot foi engolido por um comentário inline (User-agent: # old bot rule), era analisada como um token vazio. _rules_for tratava esse token como qualquer outro nome literal: um prefixo de comprimento zero casa com todos os agentes, e, por contar como correspondência *nomeada*, ele superava o grupo real User-agent: * do arquivo para todo crawler que o arquivo não menciona. Um robots.txt cuja única regra substantiva era User-agent: * / Disallow: / passava, portanto, como totalmente rastreável — tanto no relatório de acesso dos bots de IA quanto no controle de busca do próprio crawler ao vivo, que chama o mesmo is_allowed. Tokens em branco agora são ignorados, de modo que esse grupo não nomeia ninguém e o grupo curinga se aplica; o grupo nomeado mais específico continua vencendo, e um robots.txt que não nomeia ninguém continua significando que tudo é permitido.

  • CorrigidoFuncionaCorrige quatro defeitos de seleção de exportação e de validação que deixavam uma

    auditoria apresentar…

    Corrige quatro defeitos de seleção de exportação e de validação de execução que deixavam uma auditoria apresentar um resultado que não podia sustentar (#209, #210, #215, #216). O matcher de internal_all exigia apenas o token de nome de arquivo internal, então uma aba Internal parcial por tipo (por exemplo internal_html.csv, sem nenhuma linha não HTML) satisfazia a exportação mestre obrigatória Internal:All sem nenhum aviso de mestre ausente; agora o matcher também exige all. discover_exports escolhia o primeiro candidato de uma chave lógica na ordem alfabética dos nomes quando dois arquivos casavam com ela (por exemplo internal_all.csv e internal-all.csv presentes com linhas diferentes), descartando o outro em silêncio e sem nada nos metadados da execução para indicar que houve uma escolha; agora ele levanta erro, nomeando todos os candidatos. run_sf escolhia a subpasta com timestamp mais recente dentro de --out, independentemente de quando ela foi criada, então uma reexecução que saía com código 0 sem gravar nada (uma falha de inicialização que o Screaming Frog não reporta como saída diferente de zero) podia devolver as exportações de uma invocação anterior como se fossem novas; agora compara com um snapshot tirado antes de o processo começar e falha de forma explícita quando nada novo aparece. build_command só acrescentava --auth-config quando o arquivo de perfil informado já existia, iniciando em silêncio um rastreamento não autenticado quando o caminho tinha um erro de digitação ou tinha sido apagado — adequado para o padrão opcional seospiderconfig, errado para um perfil que quem chamou pediu explicitamente; agora um sf_cli.auth_config explícito ausente levanta erro antes de o Screaming Frog iniciar.

  • CorrigidoFuncionaCorrige dois defeitos de extração de conteúdo em seohead/checks/parser.py (#138, #140).

    collapse_whitespace decodificava entidades HTML uma segunda vez por cima da decodificação única que o parser lxml do BeautifulSoup já faz em todo valor que tag.get_text()/tag.get(attr) entrega a essa função — um no-op silencioso em marcação comum, mas, em uma página cujo CMS ou pipeline de importação já tinha escapado as entidades duas vezes (um artefato real e frequente), transformava uma sopa de entidades visivelmente quebrada em texto com aparência limpa e encurtava o comprimento informado abaixo do que uma aba do navegador ou um snippet de SERP realmente exibe, invertendo nos dois sentidos as verificações de tamanho de title/description. A função agora não decodifica mais nada. Além disso, a extração de links e de URLs de origem percorria o documento inteiro sem condição, então um <a>/<img> que existia apenas dentro de um <template> inerte — nunca parte do documento renderizado pela especificação HTML, nunca requisitado por um navegador ou crawler a menos que um script o clonasse — era reportado como link real na página e de fato buscado por spider.py, o mesmo modo de falha de URL fantasma já fechado para <base href> em #4; ambos os extratores agora ignoram os descendentes de <template>. <noscript> é deliberadamente mantido acessível ali, diferente da extração de texto: é marcação de fallback real e definida pela especificação, que um cliente com JavaScript desativado (e a passagem de rastreamento sem renderização dos mecanismos de busca) de fato carrega, e excluí-la esconderia do auditor uma URL genuinamente buscável. A contagem de palavras também deixa de contar o texto de descendentes de <svg>/<math> como corpo de texto (o <title> de acessibilidade de um sprite de ícones, o <text> de glifos, a notação MathML) — um cabeçalho com 20 ícones podia dobrar a contagem de palavras reportada em relação ao conteúdo real —, e essa lista de exclusão agora vive em um único lugar (content_area.TEXT_EXCLUDED_TAGS), compartilhada pelos dois extratores de texto, em vez de duas cópias que já tinham saído de sincronia.

  • CorrigidoFuncionaMantém os tokens rel completos de um link, seu atributo target e seu href bruto, e

    extrai formulários (#125).

    Mantém os tokens rel completos de um link, seu atributo target e seu href bruto (anterior à resolução), e extrai elementos <form> — método, action e se há campo de senha (#125). Seis issues catalogadas dependiam desses três fatos que estavam sendo descartados: links cross-origin inseguros (target="_blank" sem rel="noopener"/"noreferrer"), links protocol-relative (//host/path, antes da resolução), outlinks para localhost, uma página que recebe ao mesmo tempo um link interno seguido e um nofollow, uma action de formulário insegura e um formulário de senha servido de uma página HTTP sem criptografia. Todas agora correspondem a UNSAFE_CROSS_ORIGIN_LINK, PROTOCOL_RELATIVE_LINK, OUTLINK_TO_LOCALHOST, FOLLOW_AND_NOFOLLOW_INLINKS, FORM_URL_INSECURE e FORM_ON_HTTP_URL no registro. As verificações de formulário, localhost e mistura de nofollow precisam apenas de campos que todo rastreamento já registrava, então essas quatro rodam incondicionalmente; o par cross-origin e protocol-relative precisa de link_attributes.capture, desligado por padrão, porque os dados extras por aresta cresceram cerca de +50% em um rastreamento sintético de 3.387 páginas com 150 links por página — cerca de +95 bytes por aresta, +46 MiB no total, sendo que raw_href sozinho responde pela maior parte disso. O registro passa de 121 para 127 verificações.

  • CorrigidoFuncionaCorrige o report-build que renderizava em silêncio um relatório sem problemas para o SF

    Analyzer…

    Corrige o report-build que renderizava em silêncio um relatório sem problemas para um audit.json do SF Analyzer (#151). A receita documentada — sf run --tasks encadeado com report-build --format docx/xlsx/csv/md — lia as chaves findings e páginas planas, que o schema do SF não usa (os problemas ficam em issues, e os fatos das páginas em pages[].metrics); a incompatibilidade produzia um resumo 0/0/0/0 confiante para uma auditoria que tinha encontrado problemas críticos reais, sem nenhuma seção de problemas. build_report agora reconhece tanto o formato nativo seohead.site-audit/1 quanto o formato do SF Analyzer, normalizando este último para o contrato plano que os quatro escritores voltados ao leitor já entendem, antes de renderizar. --format json não foi tocado — ele já repassava o documento original corretamente, o que provou que os dados nunca estiveram ausentes. Um documento que não bate com nenhum dos dois contratos é recusado com ok: False, informando o erro de schema, em vez de ser renderizado como um entregável vazio, e o condicional morto if ... : pass que parecia fazer essa validação mas nunca fazia nada foi removido. tests/test_docs_commands_execute.py agora confere o resumo renderizado da receita documentada com os totais do próprio audit.json, e não apenas o código de saída.

  • AlteradoFuncionaFecha duas lacunas de segurança financeira em seohead/data_sources/ (#157, #159).

    O geo_guard verificava apenas a string consultiva country, então search_volume/keyword_ideas/keyword_difficulty/serp ainda podiam chegar ao endpoint ao vivo do DataForSEO com location_code=2643 (Rússia) ou 2112 (Bielorrússia) sempre que quem chamava informasse o código numérico do alvo geográfico sem preencher também country; a guarda agora verifica location_code primeiro, pois é esse o campo que de fato é cobrado. Além disso, uma exceção de rede (URLError/TimeoutError/SSLError) durante uma chamada cobrada — o post do DataForSEO, o /set do Arsenkin e wordstat.topRequests/wordstat.dynamics/web.searchAsync do Yandex Cloud — costumava repetir o mesmo payload sem chave de idempotência, registrando apenas a tentativa que finalmente devolveu uma resposta. Nenhum dos três provedores oferece mecanismo de idempotência para esses endpoints, então uma resposta perdida não é mais repetida: a tentativa é registrada no livro de gastos (custo desconhecido, marcada como attempt_failed: network_error) e a chamada falha de vez, em vez de arriscar uma segunda cobrança. Leituras idempotentes (/check e /get do Arsenkin, polling de operações do Yandex Cloud) não foram afetadas e continuam repetindo. yandex_cloud.WebSearch.search_batch isola a submissão perdida à própria consulta, em vez de abortar o lote inteiro. metrika.py repete erros de rede da mesma forma, mas não é cobrado em dinheiro e não foi alterado; fica sinalizado para um acompanhamento caso a criação de exportação do Logs API deva receber o mesmo tratamento por motivo de cota.

  • AlteradoFuncionaFecha uma brecha de DNS rebinding em http_client() (#142): pinned_target(), a

    correção da…

    Fecha uma brecha de DNS rebinding em http_client() (#142): pinned_target(), a correção para a janela de TOCTOU descrita em #14, protegia apenas o fetch em modo lista de collect.py — os outros quatorze pontos de chamada, incluindo o motor de crawl-site do spider.py, deixavam o httpx resolver o DNS uma segunda vez, de forma independente, para abrir o socket. Assim, um resolvedor hostil que respondesse a essa segunda consulta de modo diferente da consulta da própria guarda podia alcançar 169.254.169.254 ou qualquer endereço RFC 1918, independentemente do veredito da guarda. http_client() agora monta todos os clientes sobre um transporte que fixa a conexão ao endereço que ele mesmo resolve — na primeira requisição e em cada salto de redirecionamento —, mantendo o hostname apenas para o cabeçalho Host e para o SNI do TLS. A correção é, portanto, estrutural, e não uma disciplina que cada chamador precisasse lembrar. SEOHEAD_ALLOW_PRIVATE_NETWORKS/SEOHEAD_ALLOW_PRIVATE_HOSTS continuam inalterados.

  • CorrigidoFuncionaCorrige o contrato de código de saída da CLI/MCP para falhas reportadas pelo próprio

    handler, e completa…

    Corrige o contrato de código de saída da CLI/MCP para uma falha que o próprio handler reporta, e completa SOURCE_FLAGS (#155, #156). Um handler que devolvia {"ok": false, ...} — a forma documentada pela camada de ferramentas de reportar uma falha de busca, parse ou provedor sem lançar exceção — imprimia esse JSON e saía com 0 na CLI, e devolvia um resultado normal (sem isError) pelo MCP, então uma pipeline que dependesse de $? ou um cliente que checasse apenas isError não conseguiam detectar a falha. cli.py agora sai com 1 nesse caso (o código 2 próprio do log-scan para uma execução que se contradiz continua sendo um sinal separado e documentado — ver docs/USAGE.md), e mcp_server.py levanta ToolError a partir de um wrapper compartilhado _checked(), para que o cliente veja isError. Ambos chamam um único handlers.handler_failed(), para que as duas interfaces não divirjam sobre o que conta como falha. Além disso, SOURCE_FLAGS ganhou --phrase, --keywords, --query/--queries, --seed, --counter e --before/--after — cada uma já identifica a entrada inteira de um comando do mesmo modo que --url, mas estava faltando, então um laço por linha sobre qualquer uma delas processava em silêncio apenas a primeira linha. O conjunto agora é construído por _source_flag() no ponto em que cada flag é declarada, em vez de listado à mão em separado, para que não possa sair de sincronia de novo.

  • AlteradoFuncionaExpande docs/scenarios/ de dez cadeias para cinquenta e seis, agrupadas pela pergunta

    do leitor…

    Expande docs/scenarios/ de dez cadeias para cinquenta e seis, agrupadas pela pergunta com que o leitor chega (#120). Quais cenários existem é decidido pelo mapa de cobertura, e não pelo gosto: cada um declara as issues catalogadas que resolve, e tests/test_scenario_coverage.py afirma que toda issue que este toolkit diz encontrar aparece em pelo menos um cenário, que nenhum cenário cita uma issue que o mapa não lista e que nenhum deixa de fora suas limitações. Todas as 143 issues encontráveis estão cobertas. Cada comando de cada arquivo continua sendo executado contra o site de teste no CI — a suíte roda 2.008 testes, dos quais o gate de comandos de documentação é agora o maior grupo isolado.

  • AlteradoFuncionaAfirma os próprios limites do protocolo de sitemap (#124): SITEMAP_TOO_MANY_URLS acima

    de 50.000…

    Afirma os próprios limites do protocolo de sitemap (#124): SITEMAP_TOO_MANY_URLS para mais de 50.000 entradas em um único arquivo, SITEMAP_TOO_LARGE para mais de 50 MB sem compactação, e SITEMAP_URL_DUPLICATED para uma URL declarada em mais de um sitemap, nomeando os dois documentos. Um arquivo que ultrapassa qualquer um dos limites é inválido, não apenas grande — um mecanismo de busca pode ler parte dele e descartar o resto sem que o dono do site veja nada —, e os limiares vêm do protocolo, não da configuração. Os dois parsers agora registram o tamanho em bytes e a contagem declarada de cada documento, e os problemas nomeiam o sitemap filho, não o índice. O registro passa de 118 para 121 verificações.

  • AdicionadoFuncionaAdiciona docs/GUIDELINE.md, o documento que a pessoa lê primeiro (#121).

    Adiciona docs/GUIDELINE.md, o documento que a pessoa lê primeiro (#121): o que esta ferramenta é e o que não é, uma primeira execução de ponta a ponta, como escolher a taxa de rastreamento e como saber se os erros são seus, como ler o audit.json sem ser induzido ao erro por ele, o que o arquivo de configuração muda e o que apenas custa, os seis erros que todo mundo comete no início, o que fazer quando a ferramenta está errada e o que ela não consegue responder de jeito nenhum. Linkado logo no início do README, antes da referência.

  • AdicionadoFuncionaAdiciona docs/COVERAGE_SF_ISSUES.md, gerado a partir de

    seohead/sf/core/sf_issue_map.py.

    Adiciona docs/COVERAGE_SF_ISSUES.md, gerado a partir de seohead/sf/core/sf_issue_map.py: cada uma das 320 issues do catálogo publicado da área, cada uma com exatamente um status — encontrada por uma verificação nomeada, encontrada por um comando nomeado, encontrada em parte com a parte faltante declarada, uma lacuna nomeada, ou uma decisão com seu motivo (#119). Das 212 issues dentro do escopo, 126 são encontradas hoje e 17 em parte; 41 são lacunas e 28 exigem algo deliberadamente não construído. Acessibilidade (92) e AMP (16) foram recusadas como decisões únicas, com as listas completas exibidas para que a decisão seja auditável. Um teste garante que cada ID de verificação e cada comando referenciado ainda existem, de modo que uma renomeação quebre o build, e não o documento. Substitui docs/CHECKLIST_AUDIT.md, que foi escrito sem o catálogo em mãos.

  • AlteradoFuncionaO seeder de sitemap solicita o endereço como o sitemap o publicou, e não a forma

    normalizada.

    O seeder de sitemap solicita o endereço como o sitemap o publicou, e não sua forma normalizada (#115). sitemap.crawl() devolvia apenas o loc normalizado, então um sitemap que declarava /a/ provocava a busca de /a — na maioria dos CMSs, um 301 que o crawler inventava e depois reportava como fato sobre o site, e um 404 onde a forma sem barra final nem é roteada. Cada entrada agora traz o loc como publicado, junto com loc_normalized para os consumidores que comparam por ele. Estatísticas de redirecionamento de rastreamentos anteriores semeados pelo sitemap são suspeitas por esse motivo.

  • AlteradoFuncionaReestrutura a skill de operador em um diretório controlador (#111).

    .claude/skills/ agora tem dois níveis: 21 skills de método, cada uma cobrindo uma coisa bem, e control/, que decide quais delas rodar em um site que ninguém ainda analisou. O controlador roteia em vez de repetir o conteúdo, e traz cinco sub-skills carregáveis (escopo, taxa e carga, leitura de uma auditoria, verificação e entregáveis) e um arquivo de referência com três partes (defeitos encontrados em sites no ar e o que revelou cada um, qual população cada verificação descreve e o que o toolkit não consegue responder de jeito nenhum). Os gates somente em inglês e de comandos de documentação agora cobrem todo arquivo Markdown sob um diretório de skill, e não apenas SKILL.md.

  • AdicionadoFuncionaAdiciona tests/chains/: um site de teste montado com as formas que de fato quebram

    cadeias de rastreamento.

    Adiciona tests/chains/: um site de teste montado com as formas que de fato quebram cadeias — as duas formas com e sem barra final de uma mesma URL, um corpo que não é UTF-8 válido, uma página em windows-1251, um cabeçalho do site fora de <main>, um link para fora do host, um caminho bloqueado pelo robots.txt —, rastreado em loopback, com dezessete afirmações sobre a execução como um todo, e não sobre um módulo isolado (#112). Quatro propriedades: conservação (um número não muda de significado enquanto percorre o sistema), população (um problema é sobre um membro do conjunto que ele descreve), determinismo (dois rastreamentos, dois níveis de concorrência, uma resposta) e representação (uma página diz como foi medida). As regras de população são as do próprio logscan, então uma contradição que o scanner consegue nomear é uma afirmação de teste de cadeia.

  • AlteradoFuncionareconcile_sitemap informa cada URL como foi escrita, e não como foi normalizada.

    A comparação continua acontecendo pela chave normalizada, mas um problema que citava uma forma normalizada citava uma URL que não aparecia em lugar nenhum do rastreamento — inútil para quem lê e indistinguível, para o scanner de anomalias, de um problema sobre uma página que nunca foi buscada.

  • AdicionadoFuncionaAdiciona docs/scenarios/: dez cadeias de ponta a ponta, cada uma com os comandos reais

    em ordem, o artefato resultante, o custo e aquilo que a cadeia não consegue responder (#110). O restante da documentação lista o que o toolkit tem; isto descreve o que ele faz. Linkado no README, acima da lista de ferramentas, para que um agente que avalie o repositório encontre as cadeias antes do inventário. Cada comando exibido é executado contra o site de teste por tests/test_docs_commands_execute.py, cujos extrator e gates de inglês e de contagem agora percorrem docs/ em todos os níveis, e não apenas no topo.

  • AdicionadoFuncionaAdiciona log-scan (CLI) e seo_log_scan (MCP): lê os artefatos de uma execução

    concluída e aponta…

    Adiciona log-scan (CLI) e seo_log_scan (MCP): lê os próprios artefatos de uma execução concluída e reporta afirmações que não podem ser verdadeiras ao mesmo tempo (#109). Oito regras, cada uma escrita a partir de um defeito que passou por toda a suíte de testes — um tamanho registrado que discorda do arquivo em disco, uma proporção de texto acima de 100%, uma verificação disparando mais vezes do que há páginas para disparar, um problema sobre uma URL que a execução nunca buscou, uma tag canonical tratada como redirecionamento enquanto aquela URL respondia 2xx na mesma execução, um resumo que discorda das próprias linhas, palavras contadas em uma página de zero byte e páginas medidas de duas formas em que só algumas dizem qual delas. Cada anomalia nomeia os dois valores e de onde cada um foi lido. A CLI sai com código 2 quando uma execução se contradiz, para que uma pipeline pare em vez de publicar os números.

  • AlteradoFuncionaO teste de pacing entre workers não mede mais o relógio de parede (#107).

    _DispatchGate agora lê o relógio injetado do rastreamento em vez de chamar time.monotonic() diretamente, então o teste conduz o gate com um relógio virtual que avança somente quando algo dorme: os instantes de despacho são a aritmética do próprio rastreador, e a afirmação é exata. A forma antiga comparava intervalos reais decorridos com um piso de 0,024 s e falhava em código inalterado sempre que a máquina estava ocupada.

  • AlteradoFuncionaFecha a segunda metade da auditoria de configurações não conectadas (#91).

    http.headers é mesclado a todas as requisições junto dos cabeçalhos de credencial; speed.adaptive controla o atraso do throttle e o ajuste de concorrência (os contadores de timeout e de erro de servidor continuam rodando — desistir é um mecanismo separado de recuar); discovery.hyperlinks.store / .crawl, discovery.external.store e discovery.redirects.crawl agora decidem o que o rastreamento registra e o que ele segue. discovery.canonicals.*, discovery.external.crawl e discovery.redirects.store foram removidos em vez de conectados: nomeavam capacidades que o spider não tem (seguir canonicals, rastrear entre hosts) ou um estado que não consegue reter, e uma configuração que aparece em --config-help e no manifesto da execução sem mudar nada é pior do que nenhuma configuração. O conjunto de exceções do canário de cobertura está agora vazio: cada caminho de DEFAULTS altera um resultado observável e é nomeado por um teste.

  • AlteradoFuncionaDetectar a área de conteúdo pela semântica do próprio documento quando nada estiver

    configurado…

    Detecta a área de conteúdo pela semântica do próprio documento quando nada está configurado (#96): primeiro main, depois [role="main"], depois article, registrando qual deles casou como auto_main / auto_role_main / auto_article. O padrão anterior — o body inteiro menos as tags nav e footer — contava 126 palavras de template em 433 numa postagem real do WordPress (29%), incluindo um link de “pular para o conteúdo”, e essa inflação alimentava THIN_CONTENT e LOW_TEXT_RATIO na mesma direção em todas as páginas de um template. header e aside passam a somar-se a nav e footer em DEFAULT_EXCLUDE_TAGS no caminho de fallback. Um seletor configurado continua tendo prioridade, e um seletor que não encontra nada ainda cai em fallback_default_body, em vez de detectar silenciosamente outra região.

  • AlteradoFuncionaURL_NOT_IN_SITEMAP agora compara páginas com páginas (#94).

    Comparava as URLs de um sitemap com todos os destinos do grafo de links do rastreamento. Num site real de 124 páginas, disparava 392 vezes: 362 arquivos de imagem que uma galeria linka diretamente, cinco links para outros hosts e 30 URLs que o rastreamento nunca acessou. Isso representava 74% do relatório e enterrava os achados que eram reais. Agora o lado observado são as páginas que o sitemap deveria declarar: coletadas, com resposta 2xx, em HTML, do mesmo host e indexáveis. reconcile_sitemap recebe essa população como um argumento comparable separado, então SITEMAP_ORPHAN continua verificando a acessibilidade contra todos os destinos de link e não pode inventar órfãos. O que ficou de fora é devolvido em linked_not_comparable, e não descartado.

  • CorrigidoFuncionaCorrige as verificações de canonical em sites que servem as duas formas da URL, com e sem

    barra final (#95).

    norm_url elimina a barra final de propósito, para que um canonical escrito sem ela case com a página que a tem. Mas o índice normalizado guardava só uma página por chave, e um rastreamento de um site típico de WordPress tem duas: /x (301) e /x/ (200). Ler a que foi inserida primeiro fazia CANONICAL_TO_REDIRECT apontar 78 páginas ativas cujo canonical responde 200. AuditContext agora expõe pages_by_norm, com todas as páginas de cada chave; page_by_norm devolve a variante que respondeu 2xx; e CANONICAL_TO_REDIRECT e CANONICAL_NON_INDEXABLE só disparam quando nenhuma variante os contradiz.

  • CorrigidoFuncionaCorrige size_bytes: agora é o corpo da resposta como chegou pela rede, medido antes da

    decodificação…

    Corrige size_bytes: agora é o corpo da resposta como chegou pela rede, medido antes de o corpo ser decodificado (#99). Antes era medido a partir da string já decodificada, então cada byte que não era UTF-8 válido virava U+FFFD e era recodificado em três bytes. Um WebP de 739 KB de um rastreamento real foi registrado como 1,27 MB, e o fator de inflação variava de arquivo para arquivo. Imagens, PDFs, fontes e HTML servidos em charset legado (windows-1251) estavam todos superdimensionados, e assim também a razão de texto calculada com esse denominador. O cache HTTP guarda o tamanho da rede junto com a entrada, então uma página reproduzida informa o mesmo que a busca ao vivo informou. O schema passa para http_cache.v2, e entradas v1 são buscadas de novo uma vez, em vez de reproduzidas sem tamanho.

  • AdicionadoFuncionaAdiciona docs/TOOL_REFERENCE.md, gerado a partir das definições de ferramentas MCP

    (seohead/mcp/tool_reference.py, scripts/generate_tool_reference.py): os argumentos de cada ferramenta seo_*/sf_*, com tipo e padrão, seu custo (rede, escritas, idempotência, gasto, lido do perfil ToolAnnotations) e as notas de comportamento e de falha da própria docstring. tests/test_docs_drift.py falha o build se o documento divergir das definições ou se faltar alguma ferramenta.

  • AdicionadoFuncionaAdiciona tests/test_docs_commands_execute.py: extrai cada comando seohead ...

    mostrado em README/docs/skills/exemplos…

    Adiciona tests/test_docs_commands_execute.py: extrai cada comando seohead ... mostrado em README, docs, skills e exemplos (scripts/doc_commands.py) e executa cada um offline, contra um site de fixture em loopback (tests/doc_fixtures/) e cópias materializadas de examples/, verificando saída limpa. Comandos que exigem infraestrutura real (RDAP/DNS, binário licenciado do SF, credencial de provedor pago, o servidor mcp, que nunca retorna) são ao menos analisados pelo parser de argumentos ativo. Um comando documentado que deixa de funcionar agora falha no CI, em vez de ser publicado desatualizado.

  • AlteradoFuncionaReorganiza as 21 skills técnicas de fluxo de trabalho (.claude/skills/*/SKILL.md) em um

    formato comum: Gatilho, Anti-gatilho, Pré-condições (como checklist), o Fluxo de trabalho existente, Pontos de decisão, Definição de pronto (como checklist) e Custo. Corrige a contagem desatualizada de cobertura de comandos no fim de docs/SKILLS.md. A contagem real, recalculada escaneando todos os arquivos de skill, passa a ser verificada por um novo teste de drift.

  • CorrigidoFuncionaCorrige várias contagens de ferramentas e testes que tinham divergido silenciosamente dos

    registros reais: a contagem de comandos da CLI em docs/USAGE.md, docs/COMPARISON.md, README.md e docs/TESTING.md; a contagem de ferramentas MCP em docs/TOOLS.md; a contagem da referência de ferramentas em docs/README.md; e a contagem de testes offline. As corrigidas são fixadas com um teste de regressão (test_stale_tool_counts_do_not_reappear).

  • AdicionadoFuncionaAdiciona as quatro auditorias estáticas do Lighthouse que não precisam de navegador nem

    de API de terceiros (#59): MISSING_CHARSET, MISSING_DOCTYPE, VIEWPORT_MISSING e NO_COMPRESSION, cada uma calculada a partir de evidências que um rastreamento já possui. content_encoding, meta_charset, doctype e viewport entram no vocabulário normalizado de colunas. Assim, uma exportação do SF que traga esses dados como colunas de Custom Extraction alimenta as mesmas verificações. O registro passa de 114 para 118 verificações.

  • AlteradoFuncionaConecta as dez configurações restantes do rastreador, que eram validadas e gravadas no

    manifesto da execução e descritas por --config-help, mas não eram lidas por nada (#63). limits.max_response_bytes, speed.max_delay_seconds, robots.user_agent_token e speed.stop_after_consecutive_timeouts agora configuram um comportamento que antes era fixo no código. robots.unavailable_means_stop agora define se um robots.txt inacessível ou com erro 5xx interrompe o rastreamento ou é tratado como sem restrições. Antes, um robots.txt inacessível nunca interrompia o rastreamento, independentemente da política, enquanto um 5xx sempre interrompia. Agora os dois são o mesmo caso “indisponível”, controlado pela configuração. limits.max_url_length, limits.max_query_variants_per_path, http.retry_on_timeout e discovery.follow_nofollow são comportamentos implementados agora. http.user_agent passa a ser aplicado às requisições reais, em vez de sempre enviar o padrão da ferramenta. Adiciona crawl-describe-settings (CLI) e seo_crawl_describe_settings (MCP), para que um agente descubra a superfície de configuração sem acesso ao sistema de arquivos (#23).

  • AdicionadoFuncionaAdiciona busca personalizada (tools/custom_search.py) e extração personalizada

    (tools/custom_extract.py) sobre um corpus já rastreado: filtros de presença e ausência (código-fonte bruto, texto visível, um elemento CSS nomeado ou um nó XPath) e extratores CSS/XPath/regex. Ambos informam contra qual representação rodaram: marcação estática ou DOM renderizado. A ausência é contada com honestidade: uma página cuja busca falhou fica fora do numerador e do denominador, em vez de ser contada como ausente. A extração roda cada par (documento, extrator) sob um orçamento de tempo real (SIGALRM em POSIX). Uma expressão patológica aborta só aquele documento, e a execução termina mesmo assim.

  • AdicionadoFuncionaAdiciona a classificação de posição dos links (tools/link_position.py): nav, header,

    sidebar, footer ou conteúdo, por regra ordenada sobre o caminho de ancestrais de cada link. Reaproveita a noção de conteúdo de content_area.py, em vez de criar uma segunda. Está conectada ao registro de links de crawl/spider.py atrás de link_position.classify (desligada por padrão, pois guardar uma posição por link custa memória num rastreamento grande). É agregada no site inteiro por inlink_composition de crawl/linkgraph.py, que agora alimenta o novo achado de auditoria INLINK_BOILERPLATE_ONLY, para páginas linkadas apenas a partir de trechos de template. O registro passa de 104 para 105 verificações.

  • AdicionadoFuncionaAdiciona oito cálculos de segunda passagem pós-rastreamento, que só podem ser respondidos

    depois que o rastreamento termina (issue #15): uma pontuação de link interno calculada a partir do grafo de arestas all_inlinks (LOW_LINK_SCORE); um alvo de canonical para o qual nenhum hiperlink aponta (UNLINKED_CANONICAL); detecção de loop em rel="next" e de séries sem links (PAGINATION_LOOP, UNLINKED_PAGINATION_SERIES); reciprocidade de hreflang (HREFLANG_MISSING_RETURN_LINK); agregados de composição de inlinks (ONLY_NOFOLLOW_INLINKS, ONLY_NONINDEXABLE_SOURCE_INLINKS); o caminho de descoberta mais curto a partir da semente do rastreamento (DEEP_DISCOVERY_PATH); um fallback de conteúdo misto calculado pela própria ferramenta (INSECURE_SUBRESOURCE); e agrupamento de quase-duplicatas a partir do texto armazenado das páginas (NEAR_DUPLICATE/DUPLICATE_BY_HASH), conectando tools/duplicate.py e tools/content_area.py à auditoria pela primeira vez. ORPHAN_PAGE, SITEMAP_ORPHAN e as duas novas verificações de “sem links” agora são retidas: aparecem como um pulo nomeado, e não como achado, em um rastreamento que o agregador marcou como parcial, já que “nada linka para cá” não pode ser comprovado num rastreamento truncado. O registro passa de 104 para 114 verificações.

  • AlteradoFuncionaAudita o registro do rastreador contra uma checklist externa de SEO técnico e fecha oito

    lacunas baratas e comprovadas: cinco verificações de hreflang (códigos de idioma e região inválidos, autorreferência ausente, x-default ausente, entradas duplicadas e destinos não canônicos), duas diretivas de robots (notranslate, unavailable_after) e URLs canônicas com fragmento. O registro passa de 96 para 104 verificações. Veja docs/CHECKLIST_AUDIT.md.

  • AdicionadoFuncionaAdiciona asset-weight-check: busca os CSS e JS linkados de uma página e informa

    recursos que bloqueiam a renderização, arquivos grandes demais, bibliotecas duplicadas (por hash de conteúdo), falta de minificação, falta de font-display, JS legado com polyfill e falta de compressão e de cache de longa duração.

  • AdicionadoFuncionaAdiciona crawl-site --sitemap <url> (e sitemaps.auto_discover em --config): semeia

    o rastreador nativo com as URLs declaradas no sitemap, segue os links de cada uma e reconcilia os conjuntos declarado e observado em summary.sitemap do audit.json, sob os mesmos IDs de verificação SITEMAP_ORPHAN / URL_NOT_IN_SITEMAP que o pipeline do Screaming Frog já reporta.

  • AdicionadoFuncionaAdiciona crawl-site --config-help, gerado a partir de seohead/crawl/config.py, e

    oculta --max-depth e --min-delay do --help (continuam aceitos), para que a superfície de flags pare de crescer a cada configuração do rastreador.

  • AlteradoFuncionaSepara a identificação de tecnologias em uma etapa de busca e uma etapa pura

    analyze_tech. Captura os IDs de analytics e de gerenciador de tags, em vez de apenas os nomes, e adiciona um relatório tag_coverage, que agrupa a presença por template de URL e registra como cada página foi medida.

  • AlteradoFuncionaResolve cadeias e loops de redirecionamento como uma segunda passagem sobre os destinos

    de redirect de um rastreamento concluído…

    Resolve cadeias e loops de redirecionamento como uma segunda passagem sobre os próprios destinos de redirect de um rastreamento concluído. Assim, REDIRECT_CHAIN/REDIRECT_LOOP não dependem mais do relatório nativo Redirect Chains do Screaming Frog. Uma exportação em perfil light ou uma execução de crawl-site gera os mesmos achados, sem nenhum passo extra.

  • AdicionadoFuncionaAdiciona uma área de conteúdo configurável (content_area.py) que limita a contagem de

    palavras à região principal, excluindo navegação e rodapé por padrão, sem afetar a descoberta de links. A estratégia resolvida é informada por página.

  • AlteradoFuncionaSepara duplicatas exatas de quase-duplicatas em duplicate.py: correspondências exatas

    recebem hash do texto…

    Separa duplicatas exatas de quase-duplicatas em duplicate.py: as exatas recebem hash a partir do texto extraído (e não dos bytes brutos) e ficam fora dos agrupamentos de quase-duplicatas. As comparações consideram, por padrão, só páginas indexáveis.

  • AdicionadoFuncionaAdiciona um relatório de consistência de boilerplate (boilerplate_report.py) que

    calcula hash de header, nav e footer…

    Adiciona um relatório de consistência de boilerplate (boilerplate_report.py) que calcula o hash de header, nav e footer por página e sinaliza os grupos de template minoritários.

  • AdicionadoFuncionaAdiciona extração de Markdown sem dependências (markdown_extract.py): renderização só

    da área de conteúdo…

    Adiciona extração de Markdown sem dependências (markdown_extract.py): uma renderização só da área de conteúdo e outra do documento completo.

  • AlteradoFuncionaConecta markdown_extract e boilerplate_report à CLI e à superfície MCP como

    markdown-extract/seo_markdown_extract e boilerplate-report/seo_boilerplate_report (47 ferramentas centrais, eram 45). Também adiciona a flag only_indexable, que duplicate_check já tinha na camada de handler, à assinatura MCP de seo_duplicate_check, onde ela havia sido esquecida. O caminho por URL do citability-check deixa de usar o campo text do parser, que é o documento inteiro colapsado numa linha, sem quebras de parágrafo nem de título, e passa a usar o Markdown da área de conteúdo de markdown_extract. Isso corrige tanto a diluição por boilerplate levantada na issue quanto um bug antigo: o texto simples zerava silenciosamente as dimensões Answer-Blocks e Structure-Quality em todas as URLs ativas. Ficou sem escopo de propósito o próprio campo text do parser, que continua sendo do documento inteiro. Motivo: a extração de evidências de schema em page_facts.py (links sameAs de redes sociais, breadcrumbs, regex de preço e avaliação) depende de fatos que de fato ficam em widgets de header e footer, que a área de conteúdo exclui. Também ficaram de fora as verificações THIN_CONTENT/LOW_TEXT_RATIO guiadas pelo Screaming Frog, em sf/core/rules.py, cujos word_count/text_ratio vêm das colunas de exportação do próprio Screaming Frog. São dados de terceiros, e o toolkit não tem o HTML bruto para reescopar sem re-buscar cada página, o que anularia o desenho de corpus offline sem requisições do caminho de auditoria SF. O rastreador próprio do toolkit (crawl-site) já herda o escopo da área de conteúdo de graça, pois sua contagem de palavras lê direto de parser.parse_html.

  • AlteradoFuncionaDocumenta uma convenção de nomes (docs/NAMING.md) e resolve as colisões de nome-base de

    módulos e os arquivos de teste nomeados por processo que ela encontrou. Nenhum nome de comando da CLI, handler ou ferramenta MCP mudou.

  • AdicionadoFuncionaAdiciona arquivos de integração para comunidade, citação e agentes que não usam chave.
  • AdicionadoFuncionaAdiciona a skill de fluxo de trabalho com permissão analytics-console-review e três

    receitas práticas.

  • AlteradoFuncionaDocumenta o suporte à linha de segurança atual 3.x.
  • AlteradoFuncionaExige TLS 1.2 ou superior e fixa as sondagens diretas de certificado em endereços

    públicos previamente validados.

  • AdicionadoFuncionaAdiciona um cache de respostas HTTP para crawl-site (seohead/crawl/cache.py, ativado

    por cache.mode, com padrão off, para que nenhum efeito colateral apareça por padrão). Traz semântica real de frescor HTTP: max-age/Expires, revalidação por ETag/Last-Modified, variantes sensíveis a Vary, e respeito a no-store/no-cache. Há um modo replay para depuração, registrado no manifesto e nunca como padrão, e uma flag invalidate para um recarregamento forçado explícito. Cada página buscada traz cache_status (hit/revalidated/miss). A execução traz cache_stats e cache_replay, tanto na saída do handler quanto no bloco run do audit.json, então um relatório montado em parte a partir do cache informa isso. Um acerto de cache não gera requisição e também não consome atraso de throttle nem vaga do portão de despacho concorrente. A espera é emitida dentro do próprio fetch_one, só quando uma ida e volta real pela rede está prestes a acontecer.

  • AdicionadoFuncionaAdiciona reuso orientado pelo diário em seohead/core/runlog.py (SEOHEAD_REUSE_POLICY,

    idade máxima por ferramenta em segundos; padrão vazio, ou seja, nada é reutilizado). Uma resposta anterior bem-sucedida, configurada e ainda dentro do prazo, é devolvida em vez de chamar a ferramenta de novo. Ela vem marcada com reused: true e reused_from_ts, tanto no resultado quanto na nova entrada do diário, que continua sendo gravada. O frescor é sempre medido a partir de quando o valor foi de fato buscado, e nunca é estendido pelo próprio reuso.

Planejado

Roteiro

108 abertas
Open the roadmap

Data = o dia em que a mudança chegou (data git do fragmento changelog.d/). Número = a issue que fecha. Título = primeira frase, detalhes ao clicar.