Retido

O teu plugin WordPress está retido: o que cada motivo de recusa quer mesmo dizer

O e-mail da equipa de revisão é curto e vago de propósito. Aqui fica o que cada motivo quer mesmo dizer, o que o desencadeia e o que desbloqueia realmente.

Submeteste um plugin ao wordpress.org. Duas semanas depois chega um e-mail de plugins@wordpress.org a dizer que o teu plugin foi retido pelos seguintes motivos, seguido de três ou quatro parágrafos curtos que parecem explicar-se sozinhos e não se explicam.

Já recebi esse e-mail. Duas vezes, no mesmo plugin, por dois motivos diferentes. O que se segue é o que cada motivo quer mesmo dizer — incluindo os dois erros que cometi e paguei em semanas de espera.

Não insistas com eles

O e-mail deles di-lo, e é verdade: os pedidos de estado atrasam a fila. Uma revisão demora de uma a seis semanas. Não há via rápida.

Não discutas

A equipa de revisão não é um apoio com quem se negoceia. Cada minuto a explicar por que o teu caso é diferente é um minuto que não passas a corrigir.

Leitura imediata

Cola o e-mail que recebeste.

A equipa de revisão escreve em inglês seja qual for a tua língua. Cola a mensagem deles: esta página diz-te com qual dos sete motivos estás mesmo a lidar — e o que cada um quer de ti.

Corre inteiramente no teu navegador. Nada é enviado para lado nenhum, nada é guardado, não há servidor por trás.


Primeiro, como a revisão funciona mesmo

  1. 01

    Reveem tudo de cada vez

    Não comparam a nova submissão com a anterior. Um problema não mencionado à primeira pode surgir na segunda passagem — e um changelog detalhado na tua resposta é esforço perdido.

  2. 02

    Leem o código-fonte

    Não apenas o readme, nem só os cabeçalhos. Mudar uma verificação para um sítio menos visível ou renomear uma função não resulta, e transforma uma objeção técnica num problema de confiança.

  3. 03

    O e-mail é seco de propósito

    Gerem uma fila enorme com voluntários. Cada frase pesa — relê o e-mail deles como uma passagem à parte, frase a frase, quando julgares ter acabado.


Os sete motivos

Escolhe o que corresponde ao teu e-mail. Cada cartão leva ao que o desencadeia e ao que passa.

01 Guideline 5 — trialware Limitaste algo que corre no servidor do utilizador. 02 Nome e marca O nome colide — e o nome não é tudo o que verificam. 03 A linha Contributors A tua própria conta falta no readme. 04 Plugin URI partido O URL do teu cabeçalho tem de abrir, hoje, sobre este plugin. 05 Serviços externos Cada chamada de saída tem de ser documentada, e bater certo com o código. 06 Um segredo no ZIP O teu SDK de licenças escreveu uma chave no arquivo público. 07 Categoria cheia Uma observação, não um ponto de conformidade. Responde com factos.
01

Guideline 5, o «trialware»

Um plugin não pode limitar funcionalidades que são executadas inteiramente na instalação do utilizador.

O que o desencadeia

  • Uma funcionalidade que corre inteiramente no servidor do utilizador, limitada artificialmente, com um plano pago para a desbloquear
  • O caso de manual: um modo «usa a tua própria chave de API» limitado a N utilizações por mês — a chave é do utilizador, quem paga o fornecedor é o utilizador, o cálculo não te custa nada
  • Repara no que não é o problema: cobrar é permitido, ter uma versão Pro é permitido

O que passa

  • Retirar o limite de tudo o que corre localmente
  • Passar a funcionalidade para o servidor, a teu custo — aí o limite reflete uma despesa real, e a Guideline 6 permite-o explicitamente
  • Vender suporte, atualizações ou um serviço alojado — tudo menos o desbloqueio de código que já corre na máquina do utilizador
O que resultou mesmo, e me surpreendeu

A minha primeira correção mantinha o modo local, apenas sem o teto, ao lado de um novo serviço gerido. Cumpria. Era também frágil de explicar, porque obrigava o revisor a avaliar dois caminhos de código e a acreditar em mim sobre qual deles o preço se aplicava.

A versão que passou eliminava por completo o modo local. Se não há código local, a Guideline 5 não se aplica de todo. Uma posição de conformidade simples vale mais do que uma defensável.

Ordem de grandeza: isto não é um remendo. Para mim significou apagar um modo inteiro, montar um Cloudflare Worker com a minha própria chave de API, ligar webhooks de licença com validação de assinatura, acrescentar quotas por instalação e reescrever toda a cadeia de geração. Saber a resposta demorou uma hora. Entregá-la, dias.

02

Colisão de nome e marca

não apenas no nome — inclui … os URLs deste plugin

O que o desencadeia

  • O nome apresentado, o slug, o text domain, o Plugin URI, cada ligação na tua administração, o readme, o utilizador contribuidor e o próprio domínio
  • Um conflito fora do WordPress: projetos tecnológicos sem relação, GitHub, npm, produtos SaaS, registos de marcas
  • Um nome de substituição que não é demonstravelmente teu — a autorização do outro titular não resolve nada

O que passa

  • Um nome puramente descritivo não pode colidir com a marca de ninguém
  • O mais seguro: pegar na metade descritiva do nome que eles próprios sugerem e retirar o identificador — foram eles que o escreveram, dificilmente lhe chamarão enganador
  • Põe a tua alternativa no mesmo e-mail, ou compras mais uma ida e volta de uma a seis semanas
  • Verificar se um slug está livre: api.wordpress.org/plugins/info/1.2/?action=plugin_information&request[slug]=O-TEU-SLUG devolve «Plugin not found.» quando está disponível
Três renomeações que sobreviveram a um grep dado como limpo

O nome partido por uma etiqueta HTML. O logótipo do meu site estava escrito Plug<span class="dot">Forge</span>. Nenhuma procura pelo nome completo encontra isso — e era o elemento mais visível de cada página.

Um slug ainda mais antigo. Dezenas de ligações apontavam ainda para o primeiro nome do plugin, abandonado duas renomeações antes, incluindo o botão principal. Procura todos os nomes mortos, não só o último.

O que sai pela rede. Um worker em segundo plano enviava o nome antigo no seu User-Agent a cada site terceiro que tocava. Invisível no ecrã, perfeitamente real para os servidores que o recebiam.

03

A linha Contributors

O que o desencadeia

  • O titular da conta wordpress.org que submete o plugin não consta da linha Contributors: do readme
  • Escapa muitas vezes precisamente porque a linha já existe com outros nomes — o autor de uma framework, um SDK de faturação — e por isso não parece vazia

O que passa

  • Acrescenta o utilizador da conta que submete em Contributors:
  • Se estiveres também a resolver uma questão de marca, verifica essa linha: um contribuidor construído sobre o nome recusado contradiz toda a renomeação
04

Plugin URI partido

O que o desencadeia

  • O URL devolve um 404 — correção técnica
  • O URL ainda contém o nome em conflito — é um problema de marca, ver o motivo 02
  • O URL aponta para a página inicial da tua agência em vez de para este plugin em concreto

O que passa

  • Verifica em direto, não no ficheiro: um URL corrigido no código mas nunca publicado continua a ser motivo de recusa
  • Antes de responderes, abre mesmo cada URL que a tua submissão contém
05

Serviços externos não documentados

O que o desencadeia

  • Uma chamada de saída não documentada numa secção External Services do readme: o que é enviado, quando e a que fornecedor
  • Uma descrição que já não corresponde ao código submetido — pior do que nenhuma descrição, porque se lê como ocultação e não como esquecimento

O que passa

  • Escreve essa secção em último, quando a arquitetura tiver deixado de mexer
  • Confirma que a política de privacidade que ligas a partir daí diz o mesmo
  • Nomeia cada endpoint que o plugin chama mesmo, no domínio que chama mesmo
A que quase passou

A minha política de privacidade ainda dizia que o plugin enviava o URL de uma imagem, muito depois de o código ter passado a enviar a imagem em si. Dois documentos oficiais a contradizerem-se sobre o que sai do servidor do utilizador é exatamente o tipo de discrepância para que esta secção existe. Encontrei-a uma hora antes de voltar a submeter, numa última passagem, com tudo o resto já dado como limpo.

06

Um segredo enviado no ZIP público

O que o desencadeia

  • Alguns SDK de licenças escrevem um segredo em texto simples no teu ficheiro principal — o código gerado por vezes di-lo, num comentário
  • Um ZIP montado à mão em vez de com a ferramenta de build do SDK, que remove o segredo automaticamente

O que passa

  • Se montas o teu próprio arquivo, descompacta-o e faz um grep antes de carregar
  • Dez segundos de verificação contra uma falha definitiva depois de publicada
07

«Esta categoria está cheia»

O que o desencadeia

  • Uma observação de que a tua categoria está saturada — não é um ponto de conformidade e por si só não bloqueia a aprovação

O que passa

  • Responde com uma diferença técnica verificável, não com um argumento de marketing
  • Resiste ao «melhor do que X»: é infalsificável, e uma equipa de revisão que o leia confiará menos no resto da tua submissão

Como responder

A instrução deles vale a pena seguir à letra: sê breve e não listes as tuas alterações. Reveem tudo de raiz, por isso um changelog é ruído.

  1. A confirmação do que mudou, em uma ou duas frases — a posição, não o diff
  2. Havendo renomeação, um pedido explícito para reservar o novo slug — por iniciativa própria não o fazem
  3. A tua alternativa, se restar alguma dúvida
Sobre a mecânica

Carrega a versão corrigida pela página «Add your plugin», com sessão iniciada na conta que submeteu — não em anexo de e-mail. Uma página do make.wordpress.org de 2015 diz o contrário; está desatualizada. O aviso «Text Domain» ao carregar é normal até reservarem o teu slug.

A lista que percorro antes de voltar a submeter

Cada linha vem de um ponto em que falhei. Marca-as — o teu navegador lembra-se.

A última linha foi a que mais contou: treze passagens de leitura sobre o meu próprio código não viram três erros bloqueantes, e todos apareceram nos primeiros cinco minutos de execução real. Lê-se o código para encontrar o que está errado. Executa-se para encontrar o que falta.

O que isto custa mesmo

Para uma correção de conformidade simples — documentação, cabeçalhos, contributors, URLs — algumas horas é realista.

Para a Guideline 5, sê honesto contigo: estás a mudar o modelo de negócio do produto e provavelmente a construir infraestrutura de servidor que não tinhas. Entre a minha primeira recusa e a submissão final passaram nove dias, dois nomes recusados, um Cloudflare Worker, uma integração de webhooks e três erros que só apareceram quando parei de ler e comecei a executar.

As regras não são arbitrárias, e assim que se vê o padrão por trás delas são coerentes: o diretório aloja software livre que funciona, e tudo é julgado por essa medida.

Se o teu plugin está retido neste momento

Faço isto para outros autores de plugins: cada ponto do e-mail de recusa tratado, as regras ainda não levantadas verificadas também, e a resposta escrita para só teres de a enviar.

O que inclui