Pular para conteúdo

v0.6.0 — a tela da equipe: quem está nela, o que cada um faz, e o fluxo em três granulações

Decidida por: papel de Product Owner, em 2026-09-08 — a confirmar pela pessoa alocada (sro.product_owner) PR de release: #828 (development → main), mergeado em 2026-09-09T13:39:49Z · merge commit 43cb7c0 Em produção desde: 2026-09-09T13:41:41Z — ver O que o CD fez Aceitação que a sustenta: este arquivo, seção Veredito por user story.

Reavaliação de 2026-09-09, depois do delivery. Os vereditos da US1 e da US9 mudaram, e mudaram por evidência nova, não por conveniência de fechar a release: os PRs #822 e #823 entraram depois da avaliação de 2026-09-08 e fecharam exatamente os dois critérios que estavam abertos. As duas reclassificações estão nas seções das histórias, cada uma com a saída de teste que a sustenta. A US3 continua não aceita — o que falta nela é uma cronometragem, e ela não aconteceu.

A lacuna do registro de aceitação, dita antes de qualquer número. O modelo deste diretório manda apontar docs/sprints/NNN/aceitacao.md. Não existe: o último registro de aceitação desta casa é o do sprint 026. Os sprints 027, 028 e 029 têm sprint-review.md e não têm aceitacao.md, e a feature 060 não tem diretório de sprint nenhum. Enquanto isso não se corrigir, a avaliação critério a critério mora aqui — e a coluna Aceito de qualquer review que venha a ser escrita é derivada desta seção, nunca o contrário.

Por que 0.6.0 — e por que não 1.0.0 nem 0.5.1

MINOR, porque a release entrega user story nova e não retira nenhuma promessa. Não é PATCH: US1 a US5 e US9 da feature 060 não existiam na v0.5.0, e PATCH é conserto sem mudar o prometido. Não é MAJOR: nada que alguém usa deixou de valer.

Cinco delas estão aceitas — US1, US2, US4, US5 e US9 (a US1 e a US9 reavaliadas em 2026-09-09). A US3 embarcou e não está aceita. Isso não muda o número da versão: MINOR exige entregar user story nova, e cinco aceitas satisfazem isso com sobra. Muda o que a release pode declarar como conteúdo, e é o que a seção O que ficou de fora faz.

Três mudanças de comportamento existente foram pesadas uma a uma, porque é nelas que a decisão se ganha ou se perde:

O que mudou Por que não é quebra de contrato
o modelo de permissão de escrita na estrutura. pode_declarar_estrutura/4 saiu, pode_gerir_estrutura/3 entrou: o escopo de conta deixou de decidir escrita e passou a decidir a concessão de papel medido antes de trocar: zero contas perdem escrita (T006, registrado no #821). O escopo de conta continua decidindo visão. Nenhuma conta existente perde capacidade — a regra por trás dela é outra, e isso está escrito. A medida é de desenvolvimento, e a repetição em produção é pré-condição do delivery (abaixo, passo 4)
duas emendas a features publicadas — 057 FR-011 (que proibia gráfico na tela da equipe composta) e 057 FR-029 / 055 FR-013, registradas em spec.md §emendas as duas levantam proibição: a equipe composta passa a ter os gráficos que não tinha, e a definição operacional de promised passa a ser obrigatória junto do título. Quem usava a tela ganha; ninguém perde. A tabela por subequipe continua sem gráfico, que era o que a 057 protegia
MAINTAINER saiu da tela da equipe era nível de acesso de administração no GitHub apresentado ao lado de uma coluna de papel — e lido como papel por quem passa os olhos. Deixar de exibi-lo retira uma afirmação falsa, não uma promessa: a promessa da tela é quem está na equipe e que papel desempenha, e MAINTAINER nunca foi papel. O dado continua gravado. Que ele hoje não apareça em tela nenhuma é pendência, e está nomeada abaixo

E a que muda contrato interno: count_team_members_at/3 e team_members_at/3 passaram a contar pessoas distintas onde contavam vínculos. Não é quebra — é a função passando a honrar o que o nome dela promete. Mas muda números que alguém pode ter anotado: numa pessoa com dois papéis, o total de antes era 2 e o de agora é 1. Evidência do conserto: test/the_band/ontology/seon/eo/promocao_de_evidencia_test.exs:239 — "uma pessoa com dois papéis conta UMA vez".

Sobre 1.0.0, explicitamente. MAJOR aqui seria 1.0.0, e em semver 1.0.0 é a declaração de que o contrato público é estável. Esta release não pode fazer essa declaração: a API pública não existe como código — três das nove user stories da própria feature que esta release carrega não têm tarefa, e a medida de permissão de que ela depende não foi repetida em produção. Comprar um número de versão para pagar uma mudança de regra diria do produto algo que não é verdade. Semver §4 é o texto: em 0.y.z o contrato público não é estável, e mudança incompatível cabe no MINOR.

Nota de 2026-09-09: a frase anterior dizia que a 061 "está num worktree e não foi mergeada". Deixou de ser verdade quanto ao texto — o #830 mergeou a spec 061, a ADR 0009 e a spec 062 na development, depois desta release. Continua verdade quanto ao código, que é o que a decisão de versão depende. Corrijo aqui em vez de reescrever a frase como se ela sempre tivesse dito isso.

O que embarca

124 commits e 27 pull requests, contados contra a origem em 2026-09-09 e não de memória:

$ git rev-list --count v0.5.0..43cb7c0
125                      # 124 commits + o próprio merge de release

Os 27 PRs, todos com base=development e todos com o merge commit provado ancestral de 43cb7c0: #796–#799, #804, #806–#827.

Uma correção ao que este arquivo dizia antes. A versão de 2026-09-08 afirmava "PRs #796 a #821 (mais #797, #800, #802 e #805, que entraram por squash e não aparecem na lista de merges)". #800, #802 e #805 não são pull requests — são issues, e o número foi lido como se fosse de PR:

# O que é de facto Estado
#800 issue — a equipe padrão derivada inserida sem upsert fechada
#802 issue — ÉPICO: observabilidade da jornada com OpenTelemetry aberta
#805 issue — a espera por revisão mistura código com carimbo de release fechada

É o erro que esta casa nomeia em outro lugar: campo de ferramenta lido como coisa do domínio. #nnn no GitHub endereça issue e PR pelo mesmo espaço de numeração, e contar issue como PR infla a contagem de entrega com trabalho que não é entrega. #802 continua aberta — anunciá-la como embarcada teria sido afirmar entregue um épico que não começou.

O que entrou depois da avaliação de 2026-09-08

Estes seis não constavam da nota original, e dois deles mudam veredito:

PR O que traz Efeito na aceitação
#822 um Change por papel, e o roster_test.exs que nunca existiu fecha o AS2 da US1 — ver o veredito
#823 o cartão da subequipe e o gráfico pequeno (T029) fecha o AS7 da US9 — ver o veredito
#824 o bump do mix.exs para 0.6.0 na development passo 1 das pré-condições
#825 Problems now — oito cartões, e os limiares saindo das constantes US8 parcial, e sem tarefa — ver O que ficou de fora
#826 o limiar da parada estava escrito à mão na prosa da tela conserto dentro da US8
#827 as funcionalidades da equipe no site, e o nav deixando de esconder páginas não altera a aplicação

Feature 060 — a tela da equipe (o grosso da release)

User story Fase derivada PR
US1 — quem está na equipe, e de onde veio cada afirmação sro.accepted_deliverable — reclassificada em 2026-09-09 #817, #819, #821, #822
US2 — declarar o papel de quem a origem mostra, e alterá-lo sro.accepted_deliverable #821
US3 — a pessoa saiu, e o que ela fez continua contando sro.not_accepted_deliverable — SC-013 sem cronometragem #821
US4 — o vínculo que nunca foi sro.accepted_deliverable #821
US5 — criar o papel da organização a partir da estrutura sro.accepted_deliverable #821
US9 — o fluxo da equipe inteira sro.accepted_deliverable — reclassificada em 2026-09-09 #821, #823

Cinco aceitas de seis. A US3 é a única recusada, e o que falta nela é uma medida de tempo, não código. sro.sprint_deliverable compõe-se só dos aceitos: o que a US3 entrega está em produção e não integra o resultado declarado desta release.

O protótipo aprovado que serve de régua: specs/060-tela-da-equipe/prototipo/, com o prompt do design e o registro das decisões. O item do backlog é docs/backlog/tela-da-equipe.md.

O resto

O que PR Efeito em produção
feature 058 completa — a espera por revisão, quem trabalhou nos projetos, a taxa do pipeline (a v0.4.0 levou a 058 parcial) #798, #799, #805 sim
ADR 0007 — gestor de cotas: a cota é do usuário, um processo a governa, a porta é única, e a coleta volta de onde parou #808, #809, #811 sim — muda o comportamento da coleta sob rate limit
ADR 0008 — o vínculo observado: a participação que a ferramenta mostra conta como membro, e o papel é o que se declara #814 sim
a proveniência sai da lista de equipes e vai para a página da equipe #813 sim
correções de coleta: origem indisponível não grava execução sem jobs; conflito de Application Reference reconhecido #812, #800 sim
o site da documentação em MkDocs, e os 118 links quebrados que ele achou #797 não
os três primeiros modelos — DSM da 060, máquina de estados do vínculo, classes da EO #818 não
agentes de Design e de Documentação de Modelos; spec 059 em rascunho; épico de observabilidade #815, #810, #802 não
back-merge da v0.5.0 #796 não

Veredito por user story

A classificação decorre dos critérios, nunca do merge e nunca da marcação em tasks.md (sro.rule03.deliverable_acceptance_by_criteria). As user stories avaliadas são as atômicas materializadas pelos entregáveis desta release.

O que conta como evidência aqui: asserção nomeada no repositório, e o veredito de mix gates lido do log. O que não conta: a marcação [x] no tasks.md, que é declaração de quem implementou.

Limitação desta avaliação, declarada: não executei a suíte — o EXIT=0 com 1 926 testes é o que o #821 reporta como lido do log, e nenhuma revisão independente o confirmou (ver A lacuna de revisão). O que confirmei arquivo por arquivo é a existência da asserção que cada critério exige.

US1 — quem está na equipe, e de onde veio cada afirmação (P1)

Critério Tipo Conforme Evidência
AS1 — cada pessoa uma vez, com papel ou not declared, origem, início e subequipes funcional sim test/the_band_web/live/declarar_papel_na_linha_test.exs:74,82 (a linha oferece Declare role / Change role conforme o papel); promocao_na_tela_test.exs
AS2 — pessoa com vínculo direto e em subequipe aparece uma vez e é contada uma vez funcional sim — reavaliado em 2026-09-09 fechado pelo #822: test/the_band/ontology/seon/eo/roster_test.exs, casos "direta na equipe E numa subequipe: uma linha, dois vínculos" (:101) e "vigentes, saíram e equívocos somam o total de pessoas do roster" (:180). Executado: 16 passed
AS3 — quem saiu permanece marcado, com período e autor, e não conta entre os vigentes funcional sim saida_e_equivoco_na_tela_test.exs:93; eo/saida_declarada_test.exs
AS4 — equívoco permanece marcado, com razão, autor e data, excluído de toda medida em toda data funcional sim saida_e_equivoco_na_tela_test.exs:169
AS5 — as duas afirmações lado a lado quando origem e declaração discordam funcional sim test/the_band_web/live/duas_afirmacoes_test.exs; eo/discordancia_test.exs
AS6 — conta que não gere lê tudo e não vê ação funcional sim declarar_papel_na_linha_test.exs:272,279; saida_e_equivoco_na_tela_test.exs:232,240 — e o evento disparado direto pelo websocket é recusado pelo servidor
AS7 — a distinção sobrevive sem cor não funcional sim as marcas são asseridas em texto, nunca por classe, nos arquivos acima
SC-004 — 0 linhas exibem nível de acesso da plataforma não funcional sim refute html =~ "MAINTAINER" em promocao_na_tela_test.exs:139, papel_declarado_test.exs:155, screens_test.exs:160
SC-007 — ?tab=structure / ?tab=dashboard em 100% dos acessos, e recarregar mantém a aba não funcional sim ?tab=structure exercitado em 12 arquivos de teste, incluindo screens_test.exs e teto_de_consultas_da_equipe_test.exs
SC-011 — 0 ações de escrita para quem não gere; 100% das tentativas por evento recusadas com motivo não funcional sim test/the_band/tenants/gerir_estrutura_test.exs (os seis motivos); os dois arquivos de tela acima
SC-012 — 0 linhas removidas fisicamente não funcional sim papeis_na_estrutura_test.exs:219 — "ocultar papel sem ninguém funciona, e é MARCA — não apaga"; a migração 20260908010000 só acrescenta

Fase derivada: sro.accepted_deliverable — reclassificada em 2026-09-09. Em 2026-09-08 a fase era sro.not_accepted_deliverable, porque o AS2 tinha um caso provado e um caso sem asserção. O #822 entregou o roster_test.exs que faltava, com dezesseis casos, e os dois que importam ao AS2 estão nomeados na tabela.

O que mudou de evidência, e por que ela é melhor do que a que eu pedia. Eu havia proposto fechar o AS2 com uma conferência manual na equipe de referência — "custa dois minutos". O que chegou foi uma asserção automatizada, e ela é mais forte pela razão de sempre: repete-se a cada corrida, enquanto a conferência manual vale para o dia em que foi feita. O critério não exige dado de produção; exige que a pessoa em dois vínculos apareça uma vez e conte uma vez, e é isso que o teste afirma.

$ mix test test/the_band/ontology/seon/eo/roster_test.exs
Result: 16 passed

Por consequência, o passo 5 das pré-condições do delivery está cumprido — por teste, não por conferência.

O caso vizinho que enganava, e vale registrar. A suíte já provava dois papéis na mesma equipe contando uma pessoa — deduplicação por papel, com um team_id só no alcance. O caso da FR-009 é a deduplicação por equipe, com dois ids no alcance. O primeiro passa com o segundo quebrado, e nenhum teste punha uma pessoa numa parte para lê-la pelo roster da mãe. Dois testes que parecem o mesmo e medem coisas diferentes é como uma lacuna sobrevive a uma suíte verde.

Pendência que não é critério: MAINTAINER deixou de aparecer em tela nenhuma. O dado continua no banco e não tem consumidor visível — é lacuna a decidir (mostrar onde pertence, ou declarar que não se mostra), não defeito desta entrega.

US2 — declarar o papel de quem a origem mostra, e alterá-lo (P1)

Critério Tipo Conforme Evidência
AS1 — declarar num vínculo observado completa o mesmo vínculo; início continua desconhecido; a linha passa a dizer declarado funcional sim declarar_papel_na_linha_test.exs:126 — "declarar completa o vínculo observado — mesmo id"
AS2 — alterar registra o anterior com o período em que vigeu e o novo passa a valer funcional sim declarar_papel_na_linha_test.exs:212; eo/declarar_e_alterar_papel_test.exs
AS3 — segundo papel simultâneo é aceito e os dois aparecem funcional sim eo/alocacao_test.exs:110; declarar_e_alterar_papel_test.exs:161 — "a pessoa continua contando UMA vez: dois papéis não são duas pessoas"
AS4 — novo papel… abre sem sair da linha, e o papel criado já está selecionável funcional sim declarar_papel_na_linha_test.exs:166 — "'+ new role…' cria o papel e declara, sem sair da linha (FR-034)"; e :193, sem nome, recusado sem criar papel
AS5 — data em branco = início desconhecido, nunca hoje funcional sim declarar_papel_na_linha_test.exs:109 — "a data 'since' vem VAZIA, e o texto diz o que vazio significa"
SC-012 — 0 linhas removidas não funcional sim declarar_papel_na_linha_test.exs:237 — trocar para o mesmo papel é recusado e nada muda: a transação desfaz o encerramento

Fase derivada: sro.accepted_deliverable. Todos os cinco cenários com asserção nomeada, e o defeito mais perigoso da história — trocar para o papel que a pessoa já tem deixando uma linha encerrada e outra idêntica aberta — tem teste que reprova.

Fase da tarefa: T018, T019 e T020 → sro.successfully_performed_scrum_development_task.

US3 — a pessoa saiu, e o que ela fez continua contando (P1)

Critério Tipo Conforme Evidência
AS1 — o vínculo ganha fim D, quem registrou e quando, e nada é removido funcional sim migração 20260908010000_saida_declarada_com_autor.exs com as três colunas e as duas CHECKs; eo/saida_declarada_test.exs
AS2 — os números de período anterior a D são exatamente os mesmos funcional sim saida_e_equivoco_na_tela_test.exs e eo/saida_declarada_test.exs comparam count_team_members_at antes e depois
AS3 — data no futuro é recusada com a razão funcional sim saida_e_equivoco_na_tela_test.exs:127
AS4 — a coleta não recria o vínculo, e a tela mostra as duas afirmações funcional sim eo/coleta_nao_apaga_declaracao_test.exs; eo/vinculo_observado_test.exs; duas_afirmacoes_test.exs
AS5 — vínculo já encerrado: recusado, e a data original não é reescrita funcional sim record_team_departure/5 devolve erro nomeado com zero vigentes (T014); eo/saida_declarada_test.exs
AS6 — a linha diz se o fim foi declarado (por quem) ou constatado pela coleta, e neste caso declara a cadência funcional sim as três colunas da migração são o que torna os dois distinguíveis; o texto de FR-022 está na linha (T011)
SC-001 — registrar saída em D não altera número já apresentado para período anterior a D não funcional sim mesma evidência de AS2
SC-002 — 0 vínculos novos na coleta seguinte; 100% desses casos mostram as duas afirmações não funcional sim coleta_nao_apaga_declaracao_test.exs
SC-013 — registrar a saída em menos de 1 minuto, sem sair da aba Estrutura não funcional parcial a metade que a plataforma controla está provada: o formulário abre sob a linha, no mesmo LiveView, e a submissão não sai da aba — saida_e_equivoco_na_tela_test.exs:57,93,200. O minuto não foi cronometrado com uma pessoa

Fase derivada: sro.not_accepted_deliverable — falha em SC-013, por falta de medida. É o mesmo padrão que reprovou a 050/US1 na v0.3.0: "não por defeito, por falta de medida". A diferença material: ali o tempo dependia de rede, login e painel; aqui está limitado a três campos num LiveView, e o número de interações está provado.

Confirmado em 2026-09-09, depois do delivery: a cronometragem não aconteceu. O merge foi às 13:39:49Z e ninguém registrou o tempo de registrar uma saída. A US3 é a única das seis recusada, e é a mais barata de resolver da release inteira.

O que a fecha: cronometrar uma vez, com um relógio, no primeiro uso em produção — abrir a Estrutura, registrar uma saída com data, e anotar o tempo do clique ao resultado. Um número, e a US3 passa a aceita.

Consequência que não é só de registro: pela regra de release deste papel, o que não está aceito não se anuncia como entregue. A US3 fica fora do primeiro corte da página de novidades da 0.6.0 — uma funcionalidade que está em produção e que a página não pode anunciar, por falta de uma medida de um minuto. Está no backlog como o item mais barato da fila.

US4 — o vínculo que nunca foi (P1)

Critério Tipo Conforme Evidência
AS1 — invalidado para todo período, com razão, autor e data funcional sim saida_e_equivoco_na_tela_test.exs:169 — "registrar o equívoco tira a pessoa de TODA data"
AS2 — em vínculo observado o efeito é o mesmo; a coleta não recria; a tela mostra as duas afirmações funcional sim eo/coleta_nao_apaga_declaracao_test.exs; eo/vinculo_observado_test.exs; regra da evidência v3 (T003)
AS3 — sem razão é recusado funcional sim saida_e_equivoco_na_tela_test.exs:186 — "razão vazia é recusada, e nada é gravado"
AS4 — os textos de nunca esteve e saiu em D são distintos, e nenhum é "removida" funcional sim saida_e_equivoco_na_tela_test.exs:148 — "o texto separa equívoco de saída"; show.ex:3311 — "This is not 'left the team'."
AS5 — quem pertenceu e depois teve um segundo vínculo invalidado não é apresentado como nunca esteve funcional sim eo/discordancia_test.exs — o veredito é agregado por pessoa
SC-002 / SC-012 não funcional sim acima

Fase derivada: sro.accepted_deliverable. A história inteira com asserção nomeada, inclusive o caso agregado por pessoa, que é o que a torna difícil.

Fase da tarefa: T016 e T017 → sro.successfully_performed_scrum_development_task.

US5 — criar o papel da organização a partir da estrutura (P1)

Critério Tipo Conforme Evidência
AS1 — o papel existe para a organização, com autor e data, e aparece de imediato no seletor e em /roles funcional sim papeis_na_estrutura_test.exs:143 — "criar aqui aparece em /roles — é o MESMO papel (SC-005)". A leg "qualquer equipe da organização" é consequência do escopo organizacional, provado em :95 — "a mesma pessoa com o papel em duas equipes conta UMA vez na organização" —, e não de uma asserção no seletor de outra equipe
AS2 — código repetido na mesma organização é recusado; em outra organização não é conflito funcional sim papeis_na_estrutura_test.exs:160 e :169
AS3 — papel em uso não é removido, e a recusa diz quantos vínculos impedem funcional sim papeis_na_estrutura_test.exs:205
AS4 — os quatro do catálogo SRO aparecem marcados, sem remover, com as duas contagens funcional sim papeis_na_estrutura_test.exs:63,79
AS5 — renomear preserva os vínculos; nada é recriado funcional sim papeis_na_estrutura_test.exs:183
AS6 — o código sugerido do nome é editável funcional sim papeis_na_estrutura_test.exs:123 e :131 — "o código editado NÃO é sobrescrito pela sugestão"
SC-005 — 100% dos códigos repetidos recusados; 100% das ocultações de papel em uso recusadas com a contagem não funcional sim :160, :205
SC-012 não funcional sim :219 — ocultar é marca, não apaga

Fase derivada: sro.accepted_deliverable. Registro a nota de AS1 porque ela é o tipo de coisa que se descobre tarde: o seletor de outra equipe da organização não é exercitado diretamente. O escopo é o mesmo e a contagem por organização o prova; se alguém quiser a afirmação mais forte, é uma asserção a mais, não trabalho.

Fase da tarefa: T021 e T022 → sro.successfully_performed_scrum_development_task.

US9 — o fluxo da equipe inteira: burn, Prometido × Entregue, Monte Carlo (P3)

Critério Tipo Conforme Evidência
AS1 — burn-up e burn-down da equipe inteira, partindo dos já abertos, com o que resta como região, e o texto dizendo que não é a soma funcional sim test/the_band/work_items/fluxo_da_equipe_test.exs; test/the_band_web/live/fluxo_na_tela_test.exs; T028
AS2 — trocar a granulação reagrupa os mesmos itens; a soma de abertos e de fechados na janela é igual nas três funcional sim fluxo_da_equipe_test.exs — a igualdade das somas é o caso que prova FR-061, e está no teste porque é propriedade da agregação, não da tela
AS3 — Prometido × Entregue com a definição operacional e a declaração de que não há escopo comprometido junto do título funcional sim T027, com um caso que falha se a definição sair do título
AS4 — Monte Carlo semanal independente da granulação, com as duas hipóteses, a confiança e a proporção de rodadas que não concluíram funcional sim fluxo_na_tela_test.exs; medido no banco de desenvolvimento: a equipe IA fecha 22,1 itens/semana com 74 em aberto, e metade das rodadas zera em 4 semanas; PLATAFORMA e SQUAD GREEN não zeram no horizonte, e a tela diz isso
AS5 — abaixo do piso (menos de 6 semanas ou menos de 10 itens fechados) nenhuma previsão, e a tela diz o que falta funcional sim herdado da 057 FR-034, exercitado em fluxo_na_tela_test.exs
AS6 — a mesma consulta duas vezes devolve curvas e faixa idênticas funcional sim 057 FR-036, determinismo da simulação
AS7 — cada cartão de subequipe traz o gráfico pequeno, e clicar nele abre o Dashboard da subequipe funcional sim — reavaliado em 2026-09-09 o cartão existe desde o #823, com a faísca dentro e o cartão inteiro como porta. Ver a reavaliação abaixo, com a saída de teste
SC-008 — nenhuma célula de total; o fluxo declara que não é soma não funcional sim T028; texto de FR-060 obrigatório na seção
SC-009 — a distância entre as curvas é o aberto naquele ponto, nas três granulações não funcional sim fluxo_da_equipe_test.exs
SC-014 — previsão idêntica em duas consultas; abaixo do piso, nada e o que falta não funcional sim acima

A reavaliação do AS7, em 2026-09-09 — e a evidência que a sustenta

A avaliação de 2026-09-08 recusou a US9 porque "o cartão de subequipe não existe". Deixou de ser verdade com o #823, mergeado em 2026-09-08T21:10:36Z. Percorro o critério nas duas metades que ele tem, porque só uma delas é sobre o gráfico.

Metade 1 — cada cartão de subequipe traz o gráfico pequeno.

faisca_do_cartao/1 (lib/the_band_web/live/teams_live/show.ex:1156) desenha as duas curvas acumuladas, e é renderizada dentro do cartão (:3381 e :3388). As séries de qualquer número de subequipes saem de faiscas_dos_cartoes/4 (:1343) em duas consultas agrupadas — state_changes_by_team/4 e open_at_by_team/3 —, e não uma por cartão: a primeira versão fazia 7 por subequipe e foi reprovada pelo teto de consultas antes de subir.

A ausência não é falha do critério — é exigência da spec. Subequipe sem série na janela não recebe faísca: recebe "Nothing opened or closed in this window". É o que a FR-045 manda, textualmente: "Subequipe sem trabalho no período MUST ter a ausência dita em texto, nunca zero". Uma linha reta em zero afirmaria abriu zero e fechou zero, quando o que houve foi não ter o que observar. Lido isolado, o "cada um" do AS7 admitiria a leitura de que todo cartão precisa de <svg>; lido com a FR-045 ao lado, não admite — e por isso não levo esta ambiguidade à pessoa mantenedora: a própria spec já a resolveu.

Metade 2 — clicar no gráfico abre o Dashboard daquela subequipe.

O cartão inteiro é uma âncora para /teams/:id, e a faísca está dentro dela — logo o clique no gráfico é o clique na porta, que é o que o AS7 pede ao dizer "a mesma porta do cartão (FR-041)". E /teams/:id sem parâmetro abre o Dashboard, não a Estrutura:

# lib/the_band_web/live/teams_live/show.ex:163
defp aba_pedida(_params, socket), do: {:dashboard, socket}

É também o que a SC-007 exige ("?tab=dashboard (ou ausência) abre o Dashboard").

A evidência, executada — e não a existência da asserção. A avaliação de 2026-09-08 dizia, com franqueza, "não executei a suíte". Esta executou:

$ mix test test/the_band_web/live/equipe_composta_test.exs:159 --trace
  * test a tela da equipe composta FR-041/FR-084: cada subequipe é um CARTÃO,
    com faísca, e o cartão é porta (1577.0ms) [L#159]
Result: 1 passed, 12 excluded

$ mix test test/the_band_web/live/equipe_composta_test.exs
Result: 13 passed

$ mix test test/the_band/work_items/fluxo_da_equipe_test.exs \
           test/the_band_web/live/fluxo_na_tela_test.exs
Result: 28 passed

O caso nomeado afirma as duas metades: a[href="/teams/#{interface.id}"] svg — a âncora da subequipe com o <svg> dentro — e, para a subequipe fora da janela, que o cartão "sem faísca continua porta" mais a frase de ausência.

As correções de desenho do §6 estão aplicadas, e importam porque o critério é sobre um gráfico: o âmbar saiu da curva do fechado, o aberto é text-base-content/50 a 1,2 px e o fechado text-primary a 1,8 px com ponto final — distinção que não é só cor (055 FR-002) —, e a legenda existe uma vez sob a grade (:3405, :3411), como a régua manda.

Fase derivada: sro.accepted_deliverable — os dez critérios conformes, com evidência executada.

Fase da tarefa: T026, T027, T028 e T029 → sro.successfully_performed_scrum_development_task. A T029 deixou de ser tarefa não executada: está fechada, e o tasks.md registra por que a nota de bloqueio caiu.

Destino da user story: nenhum — não volta ao backlog. Foi aceita.

O achado de decomposição continua de pé, e muda de consequência

A spec 060 afirma, na abertura de User Scenarios, que "cada história é atômica […] e nenhuma depende de outra para ser testada". A US9 contradisse isso: o AS7 dela exige o cartão, e o cartão é requisito da US7 (FR-041, decisão 11 da própria spec). O achado não desaparece porque o veredito mudou — muda o que se faz com ele.

A partição que eu propunha deixou de ser necessária, e por isso não a proponho mais. Ela existia para permitir aceitar o fluxo sem o cartão; com o cartão construído, a US9 inteira é aceitável, e partir uma história cujos critérios todos passam seria mexer na decomposição sem ganho algum.

O que fica no lugar, e é mais desconfortável: a US9 só pôde ser aceita porque o artefato da US7 foi construído fora de ordem. Pela sro.rule01, toda user story materializada por um entregável do sprint tem de estar no sprint backlog daquele sprint — e a US7 não tem tarefa alguma em tasks.md (T001 a T029 cobrem US1–US5 e US9). Então:

  • reporto, e não aceito a US7 por conveniência. O cartão existe; os outros critérios da US7 — as medidas com composição, os projetos declarados, o alerta de trabalho fora de projeto — não foram avaliados, e a US7 permanece não aceita, com um pedaço já construído;
  • a lição é de planejamento, não de execução: uma história cujo critério depende do artefato de outra ou é reordenada, ou tem o critério movido para a história que o entrega. A decisão 11 da spec moveu o cartão para a US7 e o gráfico para a US9 — e deixou o AS7 da US9 apontando para o artefato da US7. Foi ali que a dependência entrou.

A régua da tela, e a republicação que não aconteceu

Aceitação de tela usa o protótipo como régua, e aqui a régua não está onde deveria. O veredito de Design de 2026-09-09 (decisoes-do-cartao-de-subequipe.md) alterou o cartão aprovado em 2026-09-07 em sete pontos — a matiz por subequipe fora, o vão do pipeline fora, stopped para a tabela, members no cabeçalho, o par de cores das curvas —, e o próprio §11 dele diz que "o protótipo é republicado no mesmo endereço antes de o código mudar". O código mudou primeiro, e a republicação está pendente.

Sou explícito sobre o que isso é e o que não é:

não é drift decidido pelo código sozinho as sete mudanças foram decididas pelo Design, com o dado real medido antes, e estão escritas com a razão de cada uma
é lacuna de registro o endereço aprovado (.../0be1668f-…) ainda serve o cartão de 2026-09-07; quem abrir a régua oficial vê três vãos e trilhos coloridos que a tela não tem
consequência prática a régua vigente do QA para este cartão é o §7 do veredito de Design, não o PROMPT.md. Está dito aqui para que ninguém marque falso defeito conferindo contra o arquivo errado

Isto não faz o AS7 falhar, e a razão é estrita: o objeto do AS7 é a faísca e a porta, e as duas conformam ao critério e ao §6/§7 do veredito. Os sete pontos divergentes são do cartão — requisito da US7, que não está sendo aceita.

Pendência nomeada: a republicação nos três arquivos (prototipo/team-dashboard-structure.html, prototipo/README.md, prototipo/PROMPT.md §3), por quem desempenha o papel de Design. Não fecha antes da próxima release, e é este registro que ela suja enquanto não fechar.

A pergunta aberta que é minha levar

O veredito de Design deixou uma decisão para a pessoa mantenedora, e ela é de conteúdo, não de código:

A ordem das duas medidas no cartão. open items · median wait (estoque primeiro, como na tabela) ou median wait · open items (a medida que varia mais entre subequipes primeiro — 0,16 h a 1,85 h é uma ordem de magnitude, enquanto 273 a 410 é meio fator)?

Recomendação do Design, que endosso: open items · median wait — a ordem do cartão deve ser a da tabela, senão comparar as duas apresentações exige reordenar de cabeça. É o que está implementado hoje, e o teste o fixa (rotulos_do_cartao == ["open items", "median wait"]). Confirmar ou trocar é decisão da pessoa mantenedora; enquanto não vier, o implementado segue a recomendação.

Risco residual aceito — a exceção do decimal

Decisão: aceito. hex: [ignore_advisories: ["CVE-2026-32686"]] embarca no mix.exs.

E o que estou aceitando não é o risco. É a divergência entre a base de avisos e o artefato instalado. A avaliação de alcance (docs/seguranca/2026-09-08-decimal-expoente-ilimitado.md) mediu no artefato, não deduziu: o contexto padrão do decimal 3.1.1 nasce com emax: 6144, Decimal.parse("1e1000000000") devolve :error, e o próprio registro OSV declara a faixa afetada como < 3.0.0 — casa a 3.1.1 apenas porque a range SEMVER dele não tem evento fixed. A mitigação que o aviso pede já está instalada.

Quatro razões, e a quarta é a que decide:

  1. não há caminho de exploração. Decimal aparece em uma linha de código (lib/the_band/work_items/person_work.ex:478), atrás de require_user, do on_mount e de Tenants.pode_ver/3. Não há coluna numeric, campo :decimal, nem endpoint JSON;
  2. nenhum gate é enfraquecido. A exceção é por ID: não muda severidade, não desliga o gate, não afeta outro pacote, e o achado continua sendo impresso em Ignored advisories: a cada execução. O --exit low do Sobelow não muda, e nenhum passo sai de lib/mix/tasks/gates.ex;
  3. a ferramenta denuncia a entrada obsoleta. Medido: com um ID que não casa, o mix hex.audit avisa que a entrada "can be removed" e mantém EXIT=1. A exceção grita sozinha quando deixar de ser verdadeira, em vez de emudecer para sempre;
  4. a proteção real não é a exceção — é o teste. test/the_band/decimal_limitado_test.exs reprova se a faixa do Decimal deixar de ser a corrigida. Um downgrade quebra a suíte, que é onde a regressão deve aparecer, e não depende de alguém reler uma data. Sem esse teste eu recusaria: a exceção sozinha trocaria um falso positivo por um ponto cego.

Prazo: até o registro OSV/EEF ganhar o evento fixed, e no máximo até 2026-12-07 (90 dias), quando a entrada é reexaminada mesmo que nada tenha mudado. Reavaliação obrigatória no fechamento de cada sprint enquanto durar.

Sinais que obrigam a reavaliar antes do prazo — qualquer um: o mix hex.audit avisar que a entrada não casa mais; versão nova do decimal publicada no Hex (atualizar e remover a exceção antes de qualquer outra coisa); rota nova fora de require_user que aceite número em texto; campo :decimal ou coluna numeric nova; ou qualquer chamada que afrouxe emax/emin.

O que recusei: construir expiração automática no mix gates. Seria código novo em código privilegiado para resolver problema de metadado de terceiro, e mix gates é a definição única dos gates. Menos código, mais evidência.

O que fica aberto, e não é desta release: o achado 2 da avaliação — person_work.ex:478 chama Decimal.round/2 sem limite explícito e sem tratamento de erro, com a garantia morando duas camadas abaixo, no int16 do protocolo do Postgres. Severidade baixa, sem caminho de exploração hoje. Vai ao product backlog como FR com tarefa: o teste de guarda da §7.1 mais um comentário dizendo de onde vem a garantia.

Pré-condições do delivery, em ordem de execução

O merge do PR development → main é o deploy. Nesta ordem, e nenhum passo pula:

# Passo Estado
1 bump do mix.exs para 0.6.0 na development, antes de abrir o PR de release — é a regra deste diretório, e a v0.2.0 é o registro do que acontece quando ela é ignorada feito — #824, e o CD leu 0.6.0 do mix.exs
2 aceitação confirmada pela pessoa alocada ao papel, sobre esta seção de vereditos NÃO feito antes do merge — ver abaixo
3 CI verde no PR de release. O #821 foi mergeado em 2026-09-08T18:36Z com os três checks verdes e mix gates EXIT=0, 15 gates, 1 926 testes — o PR de release repete a corrida sobre a integração feito — CI, CD e Docs na main concluíram success (runs 34358521311, 34358521354, 34358521337)
4 a migração que altera dados. 20260908010000_saida_declarada_com_autor.exs faz backfill de declared_at e cria duas CHECKs, e roda pela primeira vez sobre vínculos reais. Ensaiada em 2026-09-08 contra uma cópia restaurada do banco real — docs/producao/ensaio-2026-09-08-migracao-060.md: 90 vínculos antes e 90 depois, o UPDATE tocou 34 linhas (exatamente as que têm autor), 0 pares incompletos, e as duas CHECKs criadas sem violação, numa transação. E a ordem foi provada importante: rodada na ordem errada sobre as mesmas 90 linhas, deu check constraint "eo_declaracao_tem_autor" ... is violated by some row, a transação abortou e a constraint não nasceu feito
5 a conferência que fecha a US1: alguém com vínculo direto e em subequipe aparece em uma linha, e os três números do cabeçalho batem feito por teste — roster_test.exs, 16 casos, no #822. A US1 está aceita
6 cronometrar a US3: registrar uma saída com data, do clique ao resultado, com um relógio NÃO feito — a US3 segue sro.not_accepted_deliverable
7 a medida de permissão em produção: contar contas não-admin com escopo organization vigente e nenhum papel com a concessão gerir estrutura. São as que perderiam escrita. Em desenvolvimento foram zero, e é isso que a T006 mediu; produção é outro banco DISPENSADA pela pessoa mantenedora em 2026-09-08 — ver abaixo
8 merge, na janela combinada. Todo merge em main é produção; o CD lê a versão do mix.exs, publica ghcr.io/the-band-solution/theband:v0.6.0, cria a tag v0.6.0 e chama o webhook do Dokploy. Ninguém tagueia à mão feito — 2026-09-09T13:39:49Z; o CD fez os quatro atos, e nenhum foi à mão
9 back-merge main → development depois do merge — o squash diverge os históricos mesmo com conteúdo igual (L83, quatro reincidências) em curso — ramo chore/back-merge-v0.6.0, CI correndo em 2026-09-09T14:26Z

A dispensa do passo 7, e o que ela custa

A pessoa mantenedora aprovou seguir sem esta medida, em 2026-09-08. Registrado como dispensa, e não como medida feita: o número em produção continua desconhecido.

O que se sabe: em desenvolvimento é zero, e a T006 o mediu antes de trocar a regra. O que não se sabe: se existe, em produção, conta não-administradora com escopo organization vigente cuja pessoa não desempenhe papel com a concessão. Se existir, ela perde a escrita na estrutura neste delivery.

Por que isso toca a versão, e não é só uma pendência. A 0.6.0 — MINOR — foi decidida sob o argumento de que nenhuma das três mudanças de comportamento retira uma promessa, e a primeira delas é justamente a de permissão: "foi medida em zero contas afetadas". Com a medida dispensada, o argumento passa a apoiar-se na medida de desenvolvimento. Se depois do delivery aparecer conta afetada, a decisão de versão é reaberta — e o registro dirá que a informação faltava, não que estava errada.

O sintoma, para quem for procurar depois: uma conta que declarava papel, saída ou equívoco numa equipe passa a ver a estrutura inteira sem nenhum botão, e a recusa nomeada diz "No role of yours is granted to manage this team's structure". O caminho de volta não é rollback: é conceder a gestão ao papel dela em /roles.

A consulta, para rodar quando houver acesso — é a mesma que a T006 usou:

SELECT count(DISTINCT u.id)
  FROM users u
  JOIN tenant_access_scopes s
    ON s.user_id = u.id AND s.scope = 'organization' AND s.revoked_at IS NULL
 WHERE u.role <> 'admin'
   AND NOT EXISTS (
     SELECT 1
       FROM eo_people p
       JOIN eo_team_memberships m
         ON m.person_id = p.id AND m.ended_at IS NULL AND m.invalidated_at IS NULL
       JOIN eo_role_structure_management_grants g
         ON g.organizational_role_id = m.organizational_role_id AND g.revoked_at IS NULL
      WHERE p.id = (SELECT person_id FROM tenant_person_links
                     WHERE user_id = u.id AND invalidated_at IS NULL LIMIT 1)
   );

Zero significa que ninguém perdeu escrita. Maior que zero nomeia quem perdeu, trocando o count(DISTINCT u.id) por u.email.

As duas decisões da pessoa mantenedora, e o que cada uma custou

Ficam juntas e nomeadas, porque decisão registrada se corrige quando erra e omissão não. As duas foram tomadas em 2026-09-08, e as duas reduziram o que esta release verificou.

# Decisão Natureza O que ficou sem resposta
1 o ensaio de restauração do §6 do runbook fica para depois — "deixe isso para depois: o ensaio de restauração do §6" adiamento bloqueado o backup existe de verdade?
2 a medida de permissão em produção é dispensada (passo 7) dispensa quantas contas perderam escrita na estrutura?

1. O ensaio de restauração — adiado, e o bloqueio tem nome

O runbook §6 o exige antes de release com dado real, e esta release tem migração que altera dados (20260908010000: backfill de declared_at e duas CHECKs).

O bloqueio não é de agenda — é de recurso, e o recurso não existe. A conta no destino S3-compatível não foi criada ainda, registrado pela pessoa mantenedora em 2026-09-08: "tenho que criar a conta na S3 ainda para isso". Está escrito em docs/backlog/backup-restaurado-de-verdade.md.

A distinção importa e esta casa já a pagou: pendência de agenda fecha com trabalho; pendência de recurso ou de permissão só fecha com decisão de quem administra (L15). Tratar esta como se fosse de agenda faz com que ela seja replanejada indefinidamente — é o que aconteceu em cinco releases.

Risco aceito, dito inteiro: se a migração falhar em produção de um jeito não previsto, o caminho de volta é um backup que nunca foi restaurado. O que reduz o risco, e foi feito:

  • o ensaio da migração sobre cópia do banco real (ensaio-2026-09-08-migracao-060.md);
  • a migração roda numa transação — falha inteira, e o esquema fica como estava;
  • o rollback do §5 (reapontar o Dokploy para a imagem anterior), que não depende de backup.

O que o ensaio do passo 4 não substitui, e é a confusão que este parágrafo existe para impedir: ele responde "a migração roda sobre dado real?" — sim, medido. Não responde "o backup existe de verdade?" — não. São perguntas diferentes e parecem a mesma. A 050/US2 segue não aceita, desde a v0.1.0, e continua a primeira da fila de produção.

2. A medida de permissão — dispensada, e o número continua desconhecido

Detalhada na seção seguinte, com a consulta pronta para quando houver acesso. Confirmado em 2026-09-09: passado o delivery, a medida não foi rodada em produção. A dispensa permanece dispensa, e não virou medida feita.

Aceitação e merge, na ordem em que de facto ocorreram

O passo 2 diz "aceitação confirmada pela pessoa alocada ao papel, só depois abrir o PR de release". Não foi o que aconteceu, e registro porque é este arquivo que a ordem suja.

O PR #828 foi aberto e mergeado em 2026-09-09 carregando os vereditos de 2026-09-08, nos quais a US1 e a US9 estavam sro.not_accepted_deliverable e a US3 também. Ou seja: a release embarcou com três das seis histórias sem aceitação, e a nota de então declarava a exceção para uma delas (a US9).

O que a reavaliação de hoje muda, e o que não muda:

muda US1 e US9 passam a aceitas — e passam por evidência que já existia no código mergeado (#822 e #823 entraram antes do PR de release), não por indulgência posterior
não muda a US3 embarcou e continua não aceita; e a confirmação do papel sobre este registro continua pendente. Aceitação é ato do papel, e este documento é proposta até que a pessoa alocada a confirme

A inversão de ordem é o achado, não o veredito. Se os vereditos de hoje tivessem saído piores em vez de melhores, a release já estaria em produção do mesmo jeito — e é exactamente isso que o passo 2 existe para impedir. Reavaliar depois do merge só pôde melhorar o registro porque a evidência calhou de ser favorável; a próxima vez pode não calhar.

As medidas a repetir depois de subir

Do quickstart.md, seção "O que medir depois de subir" — trazidas para cá porque é aqui que a aceitação acontece:

# Medida Valor em desenvolvimento Em produção
1 contas não-admin com escopo organization vigente e nenhum papel com a concessão — as que perderiam escrita 0 não medido — dispensado
2 o custo das duas abas: painel 21 consultas por render, estrutura 7, os dois constantes com o tamanho da equipe (teto_de_consultas_da_equipe_test.exs) 21 / 7 não medido
3 quantas pessoas por equipe têm papel not declared — é o número que a US2 existe para baixar, e ele não cai por si 17 de 19 na equipe de referência (medido em 2026-09-06) não medido

Vazio seria pior que "não medido". Coluna em branco lê-se como esquecimento; não medido é um resultado, e diz que a pergunta continua aberta.

E as do runbook §7, que a v0.3.0 deixou sem medir e que esta release é a próxima chance de fechar:

Critério (050) Alvo Observado
SC-001 entrar e ver painel em < 2 min, de uma rede que não é a de desenvolvimento não medido
SC-002 < 15 min de procedimento, < 2 min de indisponibilidade — cronometrar a janela entre a última resposta da versão antiga e a primeira da nova não medido — a janela passou
AS4 uma sessão aberta antes do deploy continua valendo depois não medido — e é o único que não se recupera: exigia uma sessão aberta antes das 13:39Z
SC-004 zero segredos em imagem e logs (docker history, Config.Env) não medido — recuperável a qualquer momento sobre a imagem publicada
SC-005 100% das rotas de dados recusam sem sessão (27 rotas da 045) não medido — recuperável a qualquer momento

Sem alguém com um relógio no momento do merge, a 050/US1 continua não aceita — e é a terceira release seguida em que isso acontece. Estava escrito antes do merge, de novo, e de novo não foi feito.

A lição que três repetições autorizam: medida que só existe no instante do merge não sobrevive a um processo em que o merge é o clique final de uma sessão de trabalho. Duas das cinco (SC-004, SC-005) são recuperáveis agora, sobre a imagem e as rotas, e não dependem do instante — vale fechá-las em vez de esperar a próxima release. A AS4 é a que se perdeu de verdade: exigia uma sessão aberta antes do deploy, e não havia.

A lacuna de revisão

Merge não é revisão, e revisão não é aceitação. Reconferido contra a API em 2026-09-09, e o quadro é pior do que a nota de 2026-09-08 dizia:

PRs reviewRequests reviews Classificação
#808 a #821 (14) equipe The-Band-Solution/the-band, pedido aberto em todos 0 revisão não registrada
#822, #824 a #828 (6) vazio — ninguém foi pedido 0 revisão nunca pedida
#823 equipe the-band, pedida em 2026-09-09, retroativamente 0 revisão não registrada

A regressão é o achado. De #808 a #821 o procedimento estava certo: o pedido ia para a equipe, que é o que produz independência — paulossjunior é autor de todos e não pode atender ao próprio pedido, então quem atende é Adylla027 ou EduardoNFraiz, que não implementaram. A partir do #822 o pedido deixou de ser feito, e o PR de release #828 também nasceu sem revisor. Nenhum deles apareceu como pendência antes do merge, que é exatamente o que a regra prevê: PR sem revisor pedido é PR cuja revisão não vai acontecer, porque ninguém é notificado e nada entra na fila de ninguém.

Uma crença desta casa acabou de ser falsificada

O registro do papel afirmava, sobre o resíduo do PR #89: "não há como pedir revisão de PR mergeado". É falso. Pedi ao #823, já mergeado desde 2026-09-08, e a API aceitou:

$ gh api -X POST repos/The-Band-Solution/theband/pulls/823/requested_reviewers \
    -f 'team_reviewers[]=the-band'
$ gh api repos/The-Band-Solution/theband/pulls/823 --jq '.requested_teams[]?.slug'
the-band

Consequência: a revisão dos PRs mergeados sem pedido é recuperável, ao custo de uma chamada por PR. Deixa de ser resíduo permanente e passa a ser pendência que fecha com trabalho — inclusive a do #89, aberta desde a feature 001. Era, mais uma vez, pendência tratada como irreparável sem ninguém ter tentado.

O reparo que falta, e que não completei porque o ambiente bloqueou a chamada em lote:

for n in 822 824 825 826 827 828; do
  gh api -X POST repos/The-Band-Solution/theband/pulls/$n/requested_reviewers \
    -f 'team_reviewers[]=the-band'
done
gh api repos/The-Band-Solution/theband/pulls/<n> --jq '.requested_teams[]?.slug'  # conferir

Vazio prova ausência de registro, não ausência de leitura — e por isso a classificação das duas primeiras linhas é não registrada e nunca pedida, e nenhuma é não ocorreu. Se a pessoa mantenedora leu e concordou, o registro correto é revisão atestada, sem registro, com a data e a frase dela; enquanto isso não for dito, fica como está. É a quinta reincidência da L95, e o sprint-review 029 já a registrou com a mesma formulação.

O que a 058 fez de diferente, e vale copiar: depois do merge do #798, três revisões independentes por agente — segurança (OWASP, 7 achados), QA (8 achados) e desenho —, e as três acharam coisa que os gates não pegam, inclusive dois casos de teste de isolamento comparando [] == []. Está escrito em docs/sprints/029-medidas-da-equipe/sprint-review.md §A revisão independente. Os PRs da 060 não têm o equivalente. Para o #821, que é o maior PR desta release, a única revisão que existe é a de segurança da exceção do decimal — que cobre uma dependência, não a feature.

O que fecha a causa, e é decisão de infraestrutura, fora deste papel: abrir os PRs com identidade de agente, bot ou GitHub App. O implementador passaria a ser autor de fato, e quem revisa poderia aprovar formalmente. Apontar isso é deste papel, porque é este registro que a lacuna suja.

O que ficou de fora, e por quê

O que Por quê Destino
US3 — a saída declarada está em produção e continua não aceita: SC-013 nunca foi cronometrado não sai do sprint; fecha com uma medida de tempo. Não é anunciada na página de novidades
US6 — as subequipes: quem compõe, desde quando especificada, sem tarefa product backlog
US7 — o Dashboard reorganizado: cartão como porta, medidas com composição, projetos declarados, alerta de trabalho fora de projeto especificada, sem tarefa — e com o cartão já construído dentro da T028/T029 product backlog. Os critérios não avaliados continuam não avaliados: a US7 é não aceita com um pedaço em produção
US8 — a visão do gestor: Problems now e as pessoas com o que fazem especificada, sem tarefa — e parcialmente implementada pelo #825 e #826: oito cartões, e os limiares saindo das constantes para team_dashboard_thresholds.yaml. O próprio PR declara o que não fecha: o perfil de cada membro, as tarefas de cada um como seção própria, e dois cartões que dependem de consulta e regra que não existem product backlog. Não avaliada, logo não aceita — e não anunciada na página. Precisa de tarefas antes de veredito
US10 a US12 — os quatro gráficos por membro (WIP, prometido × realizado, throughput, Monte Carlo) especificadas em 2026-09-08 em spec-graficos-por-membro.md, sem protótipo aprovado — e a casa não implementa tela sem ele product backlog, bloqueadas no Design: o protótipo desta aba não existe
spec 061 — a API pública está num worktree e não foi mergeada fora desta release; nada nela embarca
050/US1 (o endereço estável) e 050/US2 (os dados sobrevivem) AS4, AS5 e SC-001 sem evidência; o ensaio do §6 do runbook nunca aconteceu 050/US1 é medível neste merge (passos das medidas do release); 050/US2 continua bloqueada em marco da pessoa
o achado 2 do decimal (person_work.ex:478) severidade baixa, sem caminho de exploração product backlog, como FR com tarefa: teste de guarda mais o comentário da procedência
MAINTAINER sem consumidor visível saiu da tela da equipe e não entrou em nenhuma outra; o dado continua gravado decisão a tomar: onde pertence, ou declarar que não se mostra

Nada recusado embarca escondido. Três coisas embarcaram sem aceitação e estão nomeadas acima: a US3 (recusada por falta de medida), a US7 parcial (o cartão) e a US8 parcial (Problems now). A US9, que na nota de 2026-09-08 era o caso declarado, passou a aceita — e o que ficou no lugar dela é pior de forma, porque US7 e US8 embarcaram sem tarefa alguma: escopo que entrou sem passar pelo planejamento (sro.rule01).

A regra de release e a de sprint são a mesma, e vale dizer o que ela implica aqui: só entregável aceito compõe release, do mesmo modo que só aceito compõe sro.sprint_deliverable. Então o conteúdo declarado da v0.6.0 são as cinco histórias aceitas — US1, US2, US4, US5 e US9. O resto está em produção como exceção declarada, e é assim que a página de novidades vai tratá-lo: não anuncia.

O que o CD fez

Preenchido em 2026-09-09 lido do log da corrida 34358521354, job "imagem, tag e delivery", conclusão success. Nenhum campo aqui saiu de memória (L60).

Passo Evidência
imagem ghcr.io/the-band-solution/theband:v0.6.0 — digest sha256:59ce8e25d78848d9da0c1dc38df27fae468265539f15de6f0dbd3b20d0b74340, publicada às 13:41:38Z
latest o mesmo digest — latest é apontador, nunca identidade, e aqui aponta para a v0.6.0
tag git v0.6.0 → 43cb7c0, criada pelo workflow às 13:41:40Z (* [new tag] v0.6.0 -> v0.6.0). Ninguém tagueou à mão
delivery webhook aceito às 13:41:41Z — {"message":"Application deployed successfully"}; o Dokploy puxa :latest e reimplanta
merge commit, não squash 43cb7c0 tem dois pais, e todos os 26 merge commits dos 27 PRs são ancestrais dele — verificado com git merge-base --is-ancestor. A main continua com o histórico ligado (L92)
a versão veio do mix.exs o passo "a versão vem do mix.exs, e versão repetida FALHA nomeando" concluiu sem falha, logo 0.6.0 não estava publicada antes
migração no boot não conferida — não abri o log do contêiner. É o único campo desta tabela sem evidência, e fica declarado como tal em vez de presumido a partir do success do workflow, que mede o deploy, não o boot

Que a v0.6.0 responde, medido de fora

$ curl -o /dev/null -w "%{http_code}" -L https://app.theband.dev/sign-in
200
$ curl -o /dev/null -w "%{http_code}" -L http://theband.dev/docs/
200
$ curl -o /dev/null -w "%{http_code}" -L http://theband.dev/docs/funcionalidades/tela-da-equipe/
200

HTTP 200 prova que responde; não prova qual versão responde. A aplicação não expõe a própria versão em lugar algum — não há rota de versão, não há leitura de Application.spec(:the_band, :vsn), conferido no código em 2026-09-09. Então a afirmação "a v0.6.0 está no ar" apoia-se na cadeia do CD (imagem publicada → webhook aceito → Dokploy puxa :latest), e não numa resposta da própria aplicação.

Isso é precisamente a lacuna que a regra nova de release manda fechar, e é a razão de o primeiro item do backlog dela ser a plataforma tem de saber qual versão está servindo — docs/backlog/a-versao-em-producao-na-pagina.md.

Ensaio de restauração (FR-008)

A migração desta release foi ensaiada contra dado real em 2026-09-08 — docs/producao/ensaio-2026-09-08-migracao-060.md. Números: 90 vínculos antes e depois, backfill em 34 linhas, 0 pares incompletos, duas CHECKs sem violação; e a ordem errada reprovada de propósito, sobre as mesmas 90 linhas.

O ensaio do §6 do runbook — o do backup do S3 — continua NÃO feito, por decisão registrada de 2026-09-08 e bloqueado na conta do S3, que não existe. Ele responde outra pergunta: o backup existe de verdade?. Segue como a primeira pendência de produção, e a 050/US2 segue não aceita por isso — desde a v0.1.0.

O que se observou depois

Primeira hora em produção, 2026-09-09, entre 13:39Z e 14:40Z.

O que Observado
a aplicação responde https://app.theband.dev/sign-in → HTTP 200
o site da documentação http://theband.dev/docs/ → HTTP 200; a página nova funcionalidades/tela-da-equipe/ → HTTP 200. Publicada pela corrida pages build and deployment (34358589359), success às 13:40:30Z
o CD os quatro atos concluíram, e o único job saiu success
back-merge ramo chore/back-merge-v0.6.0 com CI em curso às 14:26Z — o passo 9 está sendo feito, e não foi esquecido
erro em produção não observado, e não medido: não há painel de erro nem consulta feita. Ausência de notícia, não ausência de erro

O que NÃO se observou, e é o que esta seção costuma esconder. Registro pelo nome porque sucesso silencioso é o defeito que mais reincide nesta casa — oito ocorrências, sempre a ausência de erro lida como resultado:

Não medido Por quê importa
as cinco medidas do runbook §7 — SC-001, SC-002, AS4, SC-004, SC-005 ninguém cronometrou a janela de indisponibilidade nem conferiu se sessão aberta antes do deploy sobreviveu. A 050/US1 continua não aceita, pela terceira release seguida — e estava escrito antes do merge, de novo
a medida de permissão em produção (passo 7) dispensada; o número de contas que perderam escrita na estrutura continua desconhecido
as três medidas do quickstart.md custo das duas abas em produção, e quantas pessoas por equipe têm papel not declared — o número que a US2 existe para baixar
a migração no boot o UPDATE do backfill rodou sobre vínculos reais e ninguém leu a linha dele no log do contêiner

O padrão vale ser dito: as medidas que só se podem fazer no momento do merge são as que sistematicamente não se fazem, porque o merge acontece e a atenção vai para o que quebrou. Nada quebrou, e por isso nada foi medido — que é o mesmo resultado de não ter medido nada.