v0.9.0 — a API pública passa a existir¶
Decidida por: proposta do papel de Product Owner em 2026-09-23 — pendente de
confirmação de sro.product_owner
PR de release: a abrir (development → main) · Merge/deploy: pendente
Aceitação que a sustenta: não existe — ver "A exceção, declarada"
Por que 0.9.0, e não 0.8.1 nem 1.0.0¶
mix.exs diz 0.8.0, que é a versão em produção. Nada sai, nenhum campo público
muda de significado e nenhuma migração destrói dado — logo não é MAJOR. Não é
PATCH porque o comportamento muda para quem usa: sete rotas que hoje devolvem 404
passam a responder. MINOR: 0.8.0 → 0.9.0. Não há contrato a quebrar porque não
havia contrato: a tela que gera o token está no ar desde a v0.8.0 sem porta
alguma para usar, e esta release é a porta.
O que embarca¶
#933 — a API começa a
responder, e o Swagger fica no próprio domínio.
GET /api/v1/teams e /people, o detalhe /people/:id, a interface Swagger em
/api/docs servida do próprio domínio, e as competências de cada pessoa com a
evidência issue por issue. Materializa a US2 (o cliente chama e recebe dado do
seu tenant) e a US4 (Swagger navegável) da 061.
#934 — o detalhe da
equipe, /projects e /syncs: a FR-021 fecha.
/teams/:id, /teams/:id/members, /teams/:id/measures, mais /projects e
/syncs. As seis linhas do primeiro corte da FR-021 ficam no ar, e a SC-015 — zero
endpoints em /api/v1 fora da lista — passa a ser verificável.
#935 — o plano do servidor MCP e a avaliação de segurança dele. Só documentação: nenhum código de produção, nenhuma rota, nenhum esquema. Não muda o que quem usa vê.
Dez commits entre origin/main e origin/development; sem o #936, nenhuma
migração nova e nenhuma variável de ambiente nova.
O #936 entrou — decidido em 2026-09-23¶
O #936 foi mergeado, e esta
release o carrega. Ele corrige dois achados altos: nenhuma
leitura bem-sucedida era registrada (AccessEvents só grava recusa, e last_used_at
é carimbo sobrescrito — a FR-024 da 045 aponta o registro de acesso como o caminho
para perceber agregação, e ele não existia), e não havia limite de taxa algum.
A recomendação era que entrasse, e a tabela abaixo é o que sustentava a recomendação. Fica pelo registro da decisão — a coluna da esquerda é o que a release carrega:
| com o #936 — o que foi feito | sem o #936 | |
|---|---|---|
| limite de taxa | existe no dia em que a superfície nasce | não existe, por tempo indeterminado |
| detectar abuso depois | api_access_reads registra leitura a leitura |
impossível: nada é gravado |
| US5 da 061 (Limite de taxa por token, P2) | entregue | declarada e não entregue |
| migração | uma, aditiva: cria api_access_reads, não apaga nada, rollback não perde dado |
nenhuma |
| versão | continua 0.9.0 | 0.9.0 |
A razão é a coincidência de datas, não o tamanho do diff. O risco de não ter limite de taxa só existe a partir do instante em que as rotas respondem — e é esse instante que a release cria. Soltar sem o #936 abre a superfície e adia o controle dela; como nenhuma leitura é registrada, não se detecta depois o que não se conteve antes: sem prevenção e sem observação. A spec do MCP (062) agrava, ao dizer que herda "o limite da 061" — herdar controle inexistente é herdar zero. Custo de incluir: uma migração aditiva. Custo de adiar: uma segunda janela de deploy para um controle que deveria nascer junto com a porta.
A decisão foi tomada em 2026-09-23: o #936 entrou. A API pública nasce em produção com limite de taxa e com registro de leitura, e a US5 da 061 vai entregue em vez de declarada e ausente.
O que isso acrescenta à conferência do delivery¶
| migração | 20260922100000_registro_de_leitura_da_api — aditiva, medida: zero drop, remove ou modify; dois create. Cria api_access_reads e o índice da janela |
| rollback | não perde dado: a tabela é nova, e nada fora dela mudou |
| ensaio de restauração | entra na conferência por regra, e não por risco — é o que toda release com migração exige |
| o que muda no ar | um 429 passa a ser resposta possível da API, com retry-after e os cabeçalhos de quota. Nenhum cliente existe hoje para notar |
A janela desliza — corrigido em 2026-09-23, depois do deploy¶
A primeira versão usava janela fixa, e a limitação foi declarada no PR: na virada do minuto, o contador zerava e era possível emitir até o dobro em poucos segundos — 240 chamadas com limite de 120.
Foi corrigida logo depois de a release ir ao ar: o minuto passou a ser contado em fatias de dez segundos, e a conta é a soma das que cobrem os últimos sessenta. A rajada na virada cai de um minuto inteiro para dez segundos de imprecisão, e a soma é mais estrita que a janela declarada, nunca mais frouxa.
Esta correção NÃO está na v0.9.0. Ela entra na próxima release — a v0.9.0 foi a produção com a janela fixa, e isso fica dito aqui em vez de ser silenciosamente sobrescrito.
O número 120, e de quem ele é¶
O limite é 120 chamadas por minuto por token, e ele mora em
api.access.thresholds, na base de conhecimento — não em constante de módulo, porque
limiar em constante muda num diff e ninguém percebe.
Está marcado como proposta. Foi escolhido por quem implementou, e não medido contra uso real — não há uso real: a API nasce nesta release. Quando houver medida, o número muda em um lugar só.
A exceção, declarada¶
Não existe docs/sprints/NNN/aceitacao.md para a 061. Conferido em 2026-09-23: o
último é o do sprint 032, e nenhum cobre a 061. Só entregável aceito embarca; esta release
embarca sem registro de aceitação. O veredito por critério —
SC-010, SC-015 e o isolamento por tenant — ainda não foi percorrido com evidência.
Não houve revisão independente do desenho da API nem da avaliação de segurança. Quatro tentativas por agente falharam em 21 e 22 de setembro de 2026. A lacuna está declarada em todos os PRs e não deve ser marcada como cumprida por nenhum merge: merge não é revisão. Classificação correta: revisão não ocorreu.
O que esta release NÃO carrega, e alguém pode esperar que carregue¶
| O que | Estado |
|---|---|
| painel que leia o registro de acesso | a tabela existe e contar_por_rota/3 responde, mas quem opera consulta à mão |
| retenção do registro de leitura | ninguém poda api_access_reads; ela cresce uma linha por chamada, e o prazo é decisão de quem opera |
| o servidor MCP | o #935 é plano, não implementação: nenhum servidor sobe |
| a US6 da 061 (o que a API expõe além do primeiro corte) | P3, fora do escopo; a API é o primeiro corte da FR-021 e nada além |
| revogação de token (US3) e geração (US1) | a geração já está em produção desde a v0.8.0; a revogação não foi avaliada aqui |
| aceitação registrada da 061 | não escrita — ver a exceção |
| variável de ambiente nova | nenhuma: nada a configurar antes do merge |
O momento do delivery¶
Três perguntas antes do merge, nenhuma respondida ainda: a aceitação está confirmada pelo papel? o CI está verde no PR de release? e a página anuncia a v0.9.0 com o que ela entrega? A terceira é obrigatória desde 2026-09-09 — release que quem usa não vê anunciada é release que quem usa não recebeu. Com o #936 dentro há migração: confira o ensaio de restauração antes da janela. Sendo aditiva, a conferência é da regra, não do risco.