Impacto do Decidim 0.33 no Participa — diff de risco
Análise de impacto · v0.32.1 → 0.33 (develop)

O que o Decidim 0.33 muda e onde isso encosta no Participa

O 0.33 ainda é desenvolvimento (0.33.0.dev, sem tag). Este documento compara o último estável (v0.32.1) com a branch develop e cruza o resultado com tudo o que o Participa toca: o app, a engine decidim-govbr e as 11 gems criadas que fazem prepend no core.

Commits: 396 Arquivos alterados: 2445 Base: v0.32.1 → develop Versão alvo: 0.33.0.dev

1Contexto

1.1 O que é “0.33” hoje

O Decidim 0.33 ainda não foi lançado. Não existe tag v0.33.0 nem branch release/0.33-stable — as release branches param em 0.32-stable. O que existe é a branch develop, cujo lib/decidim/version.rb declara:

# upstream develop — lib/decidim/version.rb
module Decidim
  def self.version
    "0.33.0.dev"
  end
end

Isso define o escopo do nosso “diff”: comparar v0.32.1 (o que rodamos) com develop (o 0.33 em construção). São 396 commits e 2445 arquivos — e, como veremos, a maior parte não nos atinge. O trabalho útil é achar a interseção.

Develop é um alvo móvel

O RELEASE_NOTES.md do 0.33 é um rascunho: tem placeholders e numeração fora de ordem. Trate as mudanças citadas como “já em develop”, não como “congeladas no release”. A análise precisa ser repetida quando a release/0.33-stable existir.

1.2 Nossa superfície de acoplamento

O Participa não é um app que usa o Decidim “pela API pública”. Ele estende o Decidim por dentro. É essa intimidade que transforma um upgrade em risco — e o risco é proporcional a quantos pontos internos tocamos.

App participa (app/, config/) views Deface, initializers, CSP, Sidekiq Engine decidim-govbr content blocks, cells, admin views, SCSS/JS 11 gems criadas prepend / include em classes do core (o acoplamento mais profundo) Decidim 0.33 (develop) 396 commits · 2445 arquivos Foundation removido · participantes ocultos fila active_storage · sidekiq.yml sobrescrito Node 24 · OAuth scopes admin:* quanto mais fundo o gancho, maior a chance de o 0.33 quebrar
Três camadas nossas, todas apontando para código interno do Decidim que muda no 0.33.

A camada mais arriscada é a de baixo: as gems que fazem prepend em classes como Decidim::Meetings::Meeting ou Decidim::Proposals::ProposalForm. Um prepend não é um contrato versionado — é uma aposta de que a assinatura daquele método não vai mudar.

2Como ler um impacto

Uma mudança do upstream só nos atinge por três caminhos. Separar os três evita tanto o pânico quanto a negligência.

① O upstream avisa

Está no RELEASE_NOTES.md com um PR. Confiança: alta. É uma quebra anunciada — o time upstream quer que você aja. Ex.: “sidekiq.yml será sobrescrito”.

② O upstream mexeu num arquivo que nós enganchamos

Nosso prepend/include/Deface aponta para um arquivo que aparece no diff v0.32.1..develop. Confiança: média-alta. Não é quebra garantida — pode ser refactor interno — mas é onde o risco mora. Ex.: Decidim::Meetings::Meeting teve o scope authored_by alterado.

③ O upstream mudou um contrato que assumimos

Não tocamos o arquivo, mas dependemos de um comportamento (uma setting, um scope, um HTML). Confiança: média-baixa. O caso clássico: participantes ocultos por padrão mudam quem aparece na listagem pública — inclusive os participantes efêmeros que nós criamos.

As seções 3 a 5 varrem os três caminhos, nesta ordem.

3O que o upstream diz (caminho ①)

O diff do RELEASE_NOTES.md entre v0.32.1 e develop adiciona quatro itens. Cada um com a nossa exposição imediata.

R1 · Participantes não confirmados e gerenciados ficam ocultos por padrão alto

O que muda: perfis que não confirmaram a conta ou não aceitaram os termos de uso — e contas managed — deixam de aparecer publicamente (site e API). Base legal: GDPR Art. 25(2). PR #11036.

Nossa exposição: o login efêmero e o login gov.br criam justamente perfis que podem não ter ToS aceito. Isso pode esconder participantes legítimos das listagens, do GraphQL e das menções.

R2 · sidekiq.yml será sobrescrito no upgrade alto

O que muda: bin/rails decidim:upgrade passa a reescrever config/sidekiq.yml. Config própria deve ir para um segundo arquivo (sidekiq -C config/sidekiq.yml -C config/sidekiq.local.yml). PR #17596.

Nossa exposição: nosso config/sidekiq.yml é fortemente customizado — 15 filas (mailers, user_report, block_user, metrics, …). Um upgrade descuidado apaga isso.

R3 · Nova fila Sidekiq active_storage médio

O que muda: jobs do Active Storage passam a rodar na fila dedicada active_storage. É preciso adicioná-la e garantir um worker consumindo. PR #17520.

Nossa exposição: nosso sidekiq.yml não tem essa fila (confirmado: nenhuma ocorrência de active_storage). Uploads/anexos (inclusive do Texto Participativo e do S3/MinIO) ficariam enfileirados sem consumo.

R4 · initFoundation removido (fim do Foundation) médio

O que muda: remoção completa do que resta de Foundation-sites; window.initFoundation vira um no-op que só emite aviso. PR #16889.

# upstream develop — decidim-core/app/packs/src/decidim/index.js
window.initFoundation = (element) => {
  let message = "[Decidim] initFoundation method has previously used to initialize
  foundation-sites based tools. The Foundation CSS based interface has been removed in 0.28.
  ... Calling this method, will have no effect on your application."
}

Nossa exposição: temos código dedicado a contornar um bug do Foundation — decidim-govbr/app/packs/src/decidim/govbr/fix_foundation_trigger_open_listener.js, importado por app/packs/src/decidim/decidim_application.js. Com o Foundation fora, ele vira código morto.

4Nosso gancho → arquivo do upstream (caminho ②)

Extraímos todos os pontos em que nosso código faz prepend/include em classes do Decidim e conferimos quais desses arquivos mudaram no 0.33.

Módulo/gem nossaGancho no upstreamArquivo mudou no 0.33?
bp_proposalsDecidim::Proposals::Proposal, ProposalForm, ProposalGCellsim proposal.rb, proposal_form.rb, proposal_g_cell.rb
bp_meetingsDecidim::Meetings::Meeting, MeetingForm, Admin::Attachments*Controllersim meeting.rb, meeting_form.rb, controllers de anexos
bp_commentsComments::CommentFormCell, EditCommentModalFormCell (e 6 prepends)parcial as classes seguem; as views comment_form/show.erb e edit_comment_modal_form/show.erb mudaram
questionnairesForms::Questionnaire, ResponseForm, Admin::QuestionForm, UpdateQuestionsparcial question.rb, questionnaire_user_responses.rb, questionnaires/show.html.erb
extra_home_blocksmanifests de content block do coreparcial _content_blocks.scss, nova migration de content block — mas component_manifest.rb só mudou comentário
decidim-apartmentDecidim::Core::Seeds, System::*, Admin::*parcial core/seeds.rb mudou
app (root)ReportButtonCell, CreateReport, CommentCell, Reportparcial decidim/report.rb mudou; cells de comments com view alterada
engine decidim-govbrlayouts/decidim/header/_main_links_dropdown.html.erb, _head, admin viewssim header/_main_links_dropdown.html.erb e layouts/decidim/_head.html.erb mudaram
Boa notícia

Vários dos nossos alvos não mudaram: em decidim-comments, as classes Permissions, Comment, CommentForm, CommentCell, CreateComment, DeleteComment, CommentsController seguem intactas. O ComponentManifest (que o extra_home_blocks muta) também. Nossa estratégia de prepend continua válida — o risco é pontual, não sistêmico.

5Impacto por área (caminho ③ + detalhe)

5.1 Toolchain — Node 22 → 24

Ruby continua em 3.4.7 (igual ao nosso). O salto é o Node: o 0.33 pede .node-version = 24.18.0 e engines.node >= 24.18.0. Nosso .node-version/.tool-versions e o Dockerfile estão em 22.14.0.

Nosso (participa)0.33 (develop)Ação
Ruby3.4.73.4.7
Node22.14.024.18.0subir .node-version, .tool-versions, Dockerfile
npm≥ 11 (env local: 12)≥ 11.16.0ok
Rails8.1.3.18.1.xjá alinhado

5.2 Frontend / Foundation

Além do item R4, o diff mostra que o Decidim reescreveu componentes JS em áreas que usamos (decidim-date-picker, decidim_editor, decidim_controllers) e alterou layouts/decidim/_head.html.erb — que é justamente onde o nosso _head_extra.html.erb se pluga.

Ação direta

Remover fix_foundation_trigger_open_listener.js (e o import em decidim_application.js) quando o Foundation sair; revisar o comentário “Foundation for Participa” em _responsive-base.scss; revalidar as views de header/layout sob Deface.

5.3 Participantes ocultos (nosso ponto mais sensível de produto)

O upstream introduziu um scope novo em Decidim::UserBaseEntity:

# upstream develop — decidim-core/app/models/decidim/user_base_entity.rb
scope :profile_published, -> { confirmed.not_deleted.where(managed: false) }
scope :visible, lambda { profile_published.not_blocked.merge(
  Decidim::User.tos_accepted.or(Decidim::UserBaseEntity.where.not(type: "Decidim::User"))) }
def visible? = !blocked? && profile_published?

Isso cruza exatamente com dois recursos nossos: login efêmero (participante sem conta plena) e login gov.br (ToS pode não estar aceito). Participantes assim deixam de aparecer em perfis, listagens e API. É uma mudança de produto, não de sintaxe — precisa de decisão de UX, não só de patch.

5.4 Autenticação / OAuth

Boa notícia com ressalva. O create_omniauth_registration.rb ficou idempotente (retry em RecordNotUnique, existing_identity || create_identity) — exatamente o caso de duplo clique no callback do gov.br. E os scopes opcionais da API ganharam admin:read/admin:write. Nosso omniauth_govbr.rb não deve quebrar; vale revalidar o fluxo de callback.

5.5 Propostas, encontros e formulários

  • Propostas: proposal_form.rb agora decide o corpo conforme rich_text_editor_in_public_views? (plain_locales quando off). Afeta como o texto da proposta é normalizado — e nós temos simplificações de form.
  • Encontros: meeting.rb trocou where(decidim_author_id: author) por where(author:) no scope authored_by; meeting_form.rb e os controllers de anexos mudaram.
  • Formulários/questionários: question.rb e a query de respostas mudaram — o coração do nosso módulo decidim-module-questionnaires (o mais ativo, 71 commits).

5.6 Content blocks

O 0.33 traz uma migration nova (move_highlighted_content_banner_settings_to_content_block) e mexe em _content_blocks.scss e no title.erb do main_data. Nosso engine reaponta o bloco hero e o extra_home_blocks muta manifests — o ComponentManifest em si está estável, então a técnica sobrevive; o que muda é o conteúdo/migração.

5.7 O fork (o elo mais frágil)

community_templates

O módulo forked (decidim-bp_templates) é o único sem caminho de extensão — precisa de port manual para cada versão. Já é o motivo do .disabled-for-0.32/; no 0.33 será o primeiro a exigir trabalho. Planeje-o antes de iniciar o upgrade.

6Matriz de risco

Severidade (quanto dói se quebrar) × confiança (quão certo é que quebra).

confiança de que quebra → severidade → sidekiq.yml sobrescrito participantes ocultos prepends (proposals/meetings) views de comments/formulários Node 24 fila active_storage Foundation/initFoundation (código nosso vira no-op) OAuth idempotente (nos ajuda)
O canto superior direito (alta severidade, alta confiança) pede ação antes de começar o upgrade.
ItemSeveridadeConfiançaEsforço
Preservar as 15 filas do sidekiq.ymlaltoalta (anunciado)baixo — usar 2º arquivo de config
Participantes ocultos (efêmero/gov.br)altomédia-altamédio — decisão de produto + testes
Adicionar fila active_storagemédioalta (anunciado)baixo
prepends em proposals/meetingsmédiomédiamédio — revisar assinaturas
Views de comments / formuláriosmédiomédiamédio
Node 22 → 24baixo-médioaltabaixo
Foundation / JS própriobaixoaltabaixo — remover código morto
Fork community_templatesaltomédiaalto — port manual

7Plano de ação

Um roteiro no formato que o time já usa — Initiative → ciclo de trabalho.

🚀 Initiative: “Prontidão para o Decidim 0.33”

Antes de tocar no Gemfile:

  • Congelar a análise numa revisão de develop (hoje 0.33.dev); repetir quando surgir release/0.33-stable.
  • Mover as filas customizadas para config/sidekiq.local.yml e ajustar o comando do Sidekiq (R2).
  • Adicionar a fila active_storage ao Sidekiq (R3).
  • Remover fix_foundation_trigger_open_listener.js e o import (R4).
  • Subir Node para 24.18.0 em .node-version, .tool-versions e Dockerfile.

Durante o upgrade:

  • Rodar bundle update decidim && bin/rails decidim:upgrade && bin/rails db:migrate && bin/rails data:migrate numa branch.
  • Rodar as suítes do app (spec/) e do engine (decidim-govbr) e a de cada gem tocada.
  • Revalidar manualmente: login gov.br, login efêmero, home (hero/blog/open_processes), admin de processos, comentários (resposta oficial + 5 min), formulários, anexos.

Depois:

  • Decidir o destino do fork community_templates (portar ou aceitar novo .disabled-*).
  • Reavaliar a visibilidade dos participantes efêmeros à luz da R1.

8Como ler isto

Este documento complementa docs/participa-roadmap.html (o app) e docs/participa-gems.html (as gems criadas): aqui o recorte é o futuro — o que o 0.33 muda e onde encosta no que já existe.

Limites desta análise

① É develop, não um release final — alvo móvel. ② A interseção foi feita por nome de arquivo (nosso gancho → arquivo alterado); um arquivo alterado não garante quebra, e um arquivo não alterado não garante estabilidade de comportamento. ③ Não inspecionamos o conteúdo semântico de todos os 2445 arquivos — só os críticos. Trate a matriz da seção 6 como priorização, não como veredito.

Origem dos dados

Clone parcial de github.com/decidim/decidim; git diff v0.32.1..develop (396 commits, 2445 arquivos); RELEASE_NOTES.md do develop; e os ganchos extraídos dos nossos clones em participa-gems/ e do app participa.

Impacto do Decidim 0.33 no Participa · gerado a partir de v0.32.1..develop. Fonte editável: docs/participa-0.33-impact.html.