Pular para conteúdo

Sprint 033 — Registro de aceitação

Feature: 061 — a API pública com token de acesso

Avaliado em: 2026-09-23, na development depois dos merges de #933, #934, #935 e #936, com evidência executada nesta avaliação — 149 testes dos arquivos da 061, mais sete medições escritas e rodadas de propósito para os critérios que nenhum teste nomeado cobria.

Papel: Product Owner. A versão da release foi decidida pelo agente no papel sro.product_owner_role; esta avaliação de critérios foi feita pelo agente que implementou — ver a exceção ao fim.

Regra: sro.rule03 — a fase decorre dos critérios, com evidência executada. Critério sem evidência não vira aceito.

Resumo

Quantidade
Critérios da spec 15
Conformes 13
Não conformes 2 — SC-004 e SC-007
Testes executados nos arquivos da 061 149, todos passando
Medições escritas para esta avaliação 7

As duas recusas têm naturezas diferentes. A do SC-007 é escopo: a proveniência de medida foi desenhada para o servidor MCP (feature 062) e não chegou à API. A do SC-004 é um defeito pequeno e localizado: a informação existe e é descartada uma linha antes de chegar ao log.


Os quinze, um a um

# Critério Veredito Evidência
SC-001 0 ocorrências do valor em claro em log, resposta, página e banco conforme test/the_band_web/api/segredo_nao_vaza_test.exs — quatro varreduras, e o alvo é o segredo isolado, não o valor inteiro: o id público está no banco por desenho, e varrer pelo valor completo passaria com o segredo guardado sozinho
SC-002 0 identificadores do tenant B na resposta do tenant A conforme isolamento_por_tenant_test.exs — e a guarda do mecanismo: toda consulta de domínio leva o tenant como parâmetro, conferido por telemetria
SC-003 inexistente, revogado e expirado: respostas byte a byte idênticas conforme medido nesta avaliação: os três corpos, com o request_id normalizado, são idênticos
SC-004 100% das recusas com o motivo real recuperável no log interno, as três razões distintas NÃO CONFORME medido: o log traz duas categorias — sem_cabecalho e credencial_recusada — e as três causas colapsam na segunda
SC-005 depois da revogação, 0 chamadas atendidas conforme medido: antes 200; cinco chamadas depois, 401 nas cinco
SC-006 0 métodos além de GET e HEAD conforme somente_leitura_test.exs — percorre a tabela de rotas, não uma lista à mão; rota nova sem recusa reprova
SC-007 100% dos objetos de medida com proveniência e limitações declaradas NÃO CONFORME medido: /teams/:id/measures devolve window, work, time_to_first_review, skills e open_by_person — nenhuma chave de proveniência ou de limitações da base
SC-008 0 campos onde não observado e zero medido sejam indistinguíveis conforme person_detail_test.exs — competencies: null (não houve leitura) contra [] (houve, e nada demonstrado); e median_hours: null contra zero
SC-009 percorrer mais de três páginas devolve cada item exatamente uma vez conforme person_controller_test.exs — 80 pessoas, 8 páginas, 80 ids distintos
SC-010 100% dos endpoints na descrição OpenAPI; endpoint sem descrição falha o CI conforme team_controller_test.exs compara a descrição com a tabela de rotas. Reprovou de verdade quando /people/:id entrou, e foi corrigido
SC-011 sob limite excedido por um token, outro recebe 200 conforme registro_e_limite_test.exs — a contagem é por token, e um não gasta o limite do outro
SC-012 0 linhas de token removidas fisicamente, incluindo revogação conforme medido: uma linha antes, uma depois da revogação
SC-013 a tela de tokens traz estado e último uso, sem valor nem hash conforme medido sobre o HTML renderizado: estado presente, último uso presente, valor ausente, hash ausente
SC-014 recusa por escopo devolve 404 e não 403 conforme team_detail_test.exs e person_detail_test.exs — fora do alcance e inexistente devolvem a mesma resposta
SC-015 0 endpoints em /api/v1 fora da lista da FR-021 conforme medido: 8 rotas GET, nenhuma fora

SC-004 — a causa, e por que é pequena

TheBand.Tenants.ApiTokens.autenticar/1 colapsa as causas num else único:

with {:ok, id_publico, segredo} <- partes(valor),
     %Token{} = token <- por_id_publico(id_publico),
     true <- confere?(token, segredo),
     :ativo <- Token.estado(token, agora()) do
  {:ok, carimbar(token)}
else
  _ -> {:error, :recusado}
end

A informação existe e é descartada. Token.estado/2 já calcula :ativo, :revogado ou :expirado; o _ do else a joga fora, e o plug registra motivo=credencial_recusada para as três.

A resposta ao cliente está certa e deve continuar igual — é o SC-003, e distinguir as três lá confirmaria a quem testa credencial roubada que ela existiu. O que falta é a distinção no log interno, que é onde ela serve.

Conserto: devolver {:error, :inexistente | :revogado | :expirado | :recusado} e passar o motivo ao Logger.warning que já existe. A resposta HTTP não muda.

SC-007 — escopo, e não defeito

A proveniência de medida — valor, composição, janela, origem, id e versão da regra, limitations e misinterpretations lidas da base de conhecimento — foi desenhada para o servidor MCP, na feature 062, e o envelope está especificado lá.

A API entrega o que a tela entrega: notas escritas no controlador, e a janela declarada em window. São honestas, e não são o que o SC-007 pede.

Isto não é conserto de uma linha. Exige a função pública KnowledgeBase.measurement/1, que não existe — é a tarefa T003 da 062 —, e depois o envelope em cada medida da API.


A exceção, declarada

Esta avaliação foi feita por quem implementou. O papel Product Owner decidiu a versão da release; a conferência critério a critério foi minha, e vale menos exatamente onde mais importaria.

E não houve revisão independente do desenho da API nem da avaliação de segurança que originou o #936. Quatro tentativas por agente falharam em 21 e 22 de setembro de 2026 — duas travaram sem escrever nada, duas foram recusadas por indisponibilidade da ferramenta.

Nenhum merge cumpre isso. Classificação correta: revisão não ocorreu.


O veredito

A feature 061 é aceita com duas ressalvas escritas.

Treze de quinze critérios conformes, com evidência executada. Os dois que faltam não impedem a entrega e não devem ser esquecidos:

  • SC-004 vira item de backlog: defeito pequeno, conserto localizado, sem mudança na resposta ao cliente;
  • SC-007 vira dependência declarada da feature 062: a proveniência de medida nasce lá, e quando nascer a API pode passar a usá-la.

Aceitar com ressalva escrita é diferente de aceitar em silêncio. O que fica de fora fica nomeado.