Render — os dois serviços no ar
O que foi para produção em 2026-10-15 (backend cc69555, frontend 2dbc653): P5 (47 endpoints REST) e P8 (a casca do frontend), com os gates que cada um passou. Verde = no ar. Âmbar = espera decisão sua. Cinza = fora.
Trilha: 15 pacotes, 7 fechados
Cada pacote entra por merge --no-ff no integ/render-fase-a, com gates com log. P0..P4 foram entregues na sessão anterior (fase A, commit 3c2aaed); P5 foi fechado e publicado agora; P6..P14 continuam na fila do desenho. Os números das ondas que faltam são o tamanho medido no AgentPack de onde o código sai.
Vereditos
Os dois serviços no ar
Backend render-backend-ws: deploy t5OiAPuh_PI271BNnyEiR, commit cc69555, container 657f8d4b2572. /health 200 com banco ok, /api/render/schemas 200 (contrato público) e as 47 rotas respondendo 401. Frontend render-frontend-ws: deploy qixTWdiAryB-yObcj_UYB, commit 2dbc653, container 8fcf5b400c16, https://render-v0.mp.serendiped.com com TLS válido e 200 na raiz.
O login por SSO funciona ponta a ponta
Com navegador de verdade: abrir a raiz da app manda para /auth/sso, o backend monta a authorize da Conta com client_id=render e o redirect_uri da origem do frontend, e a Conta Nommand recebe o pedido (302 para o login dela, sem erro de CSP no console). A tela /login renderiza a moldura de entrada com o botão para a Conta.
CSP conferida contra o que é servido
O nginx responde script-src 'self' 'sha256-+xIY…' e o script de tema servido tem exatamente esse SHA-256 — conferido baixando a página de produção e recalculando. O index.html ficou fora do prettier de propósito: reformatar o script quebrava o hash e a página pintaria o escuro padrão até o bundle carregar, sem erro no console. Também vieram CSP, X-Frame-Options, nosniff e Referrer-Policy.
P5 em produção — commit cc69555
47 endpoints sob /api com os mesmos caminhos do AgentPack (inclusive os legados /api/designs/** e /api/library/**), zod em params/query/body/resposta, e a borda decidindo a escrita do catálogo por empresa (D3/D14).
Gates: 26 verdes, nenhum contornado
P5 (18): prisma-validate, prisma-format-check, typecheck, lint-ratchet (129 no teto), cycles, knip, docs-check, env-example-check, test-db-migrate, test-db-drift, testes (58 suítes, 987 testes), cobertura, coverage-floor, test-env-ci, build, gitleaks×2. P8 (8): typecheck, lint, cycles, format, testes (7 suítes, 69 testes), build, build-sane e nginx-conf. Os dois gates que reprovavam no P5 foram corrigidos: o knip por trazer os testes do P4 que faltavam, e a cobertura porque a medida era de uma árvore incompleta — os pisos subiram para os medidos.
P8 — a casca que faltava
Vite 8 + React 19 nos presets do @nomad/ui, TopBar Nomad com o AppSwitcher no slug render, rotas públicas de login, RequireAuth com ?next=, sidebar, breadcrumb e paleta de comandos, dentro do shell / e /settings. Dois aprendidos de deploy ficaram registrados: o lock tem de ser gerado com o npm que o Dockerfile instala (o npm 11 da sandbox escreve uma árvore diferente) e precisa da cópia aninhada do typescript 5.9.3 que o madge exige.
Detalhe
O que foi para a main nesta tarefa
| Commit | O que é | Tamanho |
|---|---|---|
| 1b63972 | Integra pkg/p5 (rotas REST do Render) no integ/render-fase-a | 27 arquivos, +3.816 / −98 |
| 4a13f50 | Integra pkg/p8 (casca do frontend) no integ/render-fase-a | 77 arquivos, +16.021 |
| cc69555 | Fase A (P0..P5) na main — o backend publicado | merge --no-ff |
| 2dbc653 | Fase A + P8 na main — o frontend publicado | merge --no-ff |
| a8401d6 | docs(runbook): o que a subida mostrou que o roteiro errava | +125 / −17 |
| 9fea358 | chore(backend): piso de cobertura sobe para o medido | 8 pisos |
| 442eac5 | fix(test): handler de mentira sem async (fecha a catraca em 129) | 1 arquivo |
Gates por pacote
| Pacote | Resultado | Número |
|---|---|---|
| P5 · typecheck + build | passou | tsc limpo, dist/server.js gerado |
| P5 · lint:ratchet | passou | 129 avisos no teto (não subiu), 0 erros |
| P5 · knip | passou | 0 erros; exports e tipos sem uso só como aviso |
| P5 · testes | passou | 58 suítes · 987 testes · 5 pulados · 0 falhas |
| P5 · cobertura + piso | passou | src 87,63% · services 86,58% · routes 92,53% · 8/8 |
| P5 · gitleaks | passou | nenhum segredo na árvore nem nos commits |
| P8 · typecheck + lint | passou | tsc limpo; eslint 0 erro |
| P8 · testes | passou | 7 suítes · 69 testes · 0 falhas |
| P8 · build + nginx | passou | dist com 9 assets; 7/7 conferências no conf |
O que ficou de fora — e o que destrava
| Onda | Tamanho medido | O que destrava |
|---|---|---|
| P6 · tools MCP | ~5.000 linhas + 11 suítes | Portar tools/render e mcp/ e trocar o stub do /mcp (hoje responde 403 MCP_NOT_AVAILABLE para chave restrita) |
| P7 · portão de upgrade | 2 services + 1 CLI | Tabela render_approvals no lugar da leitura de task_decisions |
| P9 · motor do Render | ~40 arquivos de engine | As primitivas e o contrato gerado que o preview de tela usa |
| P10 · dados e editor | 48 operações REST escritas à mão | O editor de tela, com autosave e rascunho |
| P11 · telas | 112 arquivos de pages/Render | As telas do Studio e as rotas /render/** de verdade |
| P12 · serviço de captura | 4 arquivos + credencial | shot/ com token próprio, depois do frontend |
| P13 · suíte migrada | ~95 arquivos de teste | Fazer a cobertura voltar aos pisos do AgentPack (90/93) |
| P14 · corte de dados | 1 script + 2 runbooks | Migração do AgentPack com --dry-run obrigatório |
Próximo
- Runbook de produção — topologia, env sem valores, ordem de subida, verificação e rollback
- App do Render — casca no ar; o login pela Conta funciona ponta a ponta
- API do Render — health com banco ok; /api/render/schemas é o contrato público
- Repositório — main em 2dbc653; integ/render-fase-a em 3c32974