Duas frentes, um pedido

Tirar o Render do AgentPack para uma app propria, e consertar os MCPs proxied que tem sessao. O que existe, o que falta e o que depende de voce.

2026-10-13 · sandbox agent-package-audit · base origin/main 26268c0 (o que esta no ar em agentpack-backend-ws)

bloqueado 12 bloqueios abertos (2 criticos de seguranca/execucao) decisao sua 5 decisoes travam pacotes nao publicado commit 1a67c15 so no worktree, sem push, sem merge, sem deploy gates 13 de 14 verdes; 1 vermelho com 3 falhas pre-existentes

01Em numeros

O que foi medido, o que existe e o que nao existe. Os zeros sao a parte importante.

304
arquivos mapeados
do Render mapeados no AgentPack
108 no backend (28.749 linhas) + 196 no frontend (32.473 linhas)
17
pacotes de trabalho
para construir a app Render
P-1, P-2, P0..P14 — cada um do tamanho de um agente
0
pacotes executados
da app Render
o repo PedroPaduelo/render tem 1 commit e 129 bytes (so um README). Existe desenho, nao codigo.
5
causas raiz do MCP
diagnosticadas e provadas
C1 protocolo, C2 sessao, C3 transportes, C4 catalogo sem empresa, C5 erro opaco
22
testes novos
na correcao do proxy de MCP
5 em mcp-proxy-v2 (NOVO) + 3 + 2 + 6 + 2 da rodada 2, todos contra upstream real
5
bloqueios abertos
na revisao adversarial do MCP
correcao 1 · concorrencia 2 · seguranca 2 — nenhum commit depois do 1a67c15
0
servicos novos criados
no MyPanel
render-backend-ws, render-frontend-ws e render-shot-ws sao runbook, nada foi criado
23
faltas mapeadas
no levantamento de completude
de tudo que foi pedido, do app Render ate o merge na main

Gates

GateResultadoObservacao
backend:typecheckverde
frontend:typecheckverde
jest shard 1/8verde
jest shard 2/8verde
jest shard 3/8verde
jest shard 4/8vermelho3 falhas PRE-EXISTENTES de shutdown.test.ts, iguais ao baseline. Nenhuma falha nova.
jest shard 5/8verde
jest shard 6/8verde
jest shard 7/8verde
jest shard 8/8verde
frontend:vitest mcps+renderverde
eslint dos arquivos tocadosverde
lint:ratchetverde4831 avisos, numero identico ao baseline, 0 erros
docs:gen + docs:checkverde

Leia antes de acreditar nos numeros. Gates verdes provam que os testes EXISTENTES nao regrediram. Nao provam que as revisoes adversariais aprovaram — e elas nao aprovaram: as 3 lentes voltaram com verdict 'fix'.

02A app Render nova

Fase A entrega o Render dentro do AgentPack; fase B tira de dentro e o AgentPack vira ponte.

Conta Nommandfonte unica de empresas, membros,papeis e contratosOIDC / JITlogin das pessoas nas duas appsWebhook de provisionamentoapp.contract.cancelled suspende,org.upserted marcaresumeRequestedAtAgentPack — ficaprojetos, tasks, decisoes, chaves,skills, auditoria, gateway /mcpagentpack-frontend-wsnginx :8080 · 256 MB · itemRender vira link externoagentpack-backend-ws :40001024 MB · Fastify 5 + Prisma 6 +zod 3 · projects,task_decisions, agent_keys,skillsGateway /mcp + catalogoMCPprecisa de organizationId noMcpServer antes de cadastrar oMCP do RenderRender — app novaPedroPaduelo/render, mesmaarquitetura e mesmas versoesrender-frontend-wsnginx :8080 · 256 MB · Studio ·proxy /api /mcp /auth/ssorender-backend-ws :40001024 MB · volume /data · 47rotas REST · 59 tools MCP · /mcppropriorender_projects (espelho)mesmo id do AgentPack · webhookassinado + reconciliador · FK de4 tabelasrender_approvalsportao do upgrade de designsystem · uma decisao = umatransicaorender-shot-ws :4500(opcional)Chromium · 1 GB · sem dominio ·credencial de preview por cookiehttpOnlyfase B: ponte /mcpFase A (entrega)Render mora dentro do AgentPack; nada muda por foraFase B (corte)Render mora sozinho; o AgentPack vira ponte com prefixo agentpack_renderConta Nommad e a fonte unica de empresas, membros, papeis e contratos nas duas apps.
MedidaValor
Entra no Render43% do backend · 41% do frontend
Rotas REST47 (o plano falava 54; o desenho corrigiu com criterio escrito)
Tools MCP59 — 20 render + 39 render-admin
Banco8 tabelas + 3 enums + espelhos + approvals
Nomes de wireagentpack_render_* (iguais aos de hoje)
Fica no AgentPacko core inteiro + projeto + decisao humana + chave

Compatibilidade — o que continua igual

A ponte, com as tres ressalvas aceitas

A virada. No corte, o AgentPack cadastra o /mcp do Render como MCP proxied com toolPrefix agentpack_render, de modo que uma URL so e os mesmos nomes continuem valendo. Hoje o AgentPack publica agentpack_render_ como built-in e o catalogo proxied descarta nomes que colidem com built-in (mcp/catalog.ts:292) — por isso a ponte so funciona DEPOIS de remover RENDER_TOOLS do registro. E mecanismo de virada, nao de convivencia.

03O proxy de MCP antes

A sessao do destino e por (chave, projeto), nao por conversa: duas conversas da mesma chave dividem a MESMA janela do browser. O gateway e stateless por decisao (ADR-011), entao nao existe sessao de quem chama.

O CAMINHO DE UMA CHAMADA PROXIEDAgente (Claude Code,Motor)Gateway /mcpSTATELESS —routes/mcp.ts:102catalogo.ts findTool· toolset proxiedproxy-call.tscallProxied · escopo= principal + projetoPool LRU · chave =URL + headers +escopo · TTL ocioso 5min · teto 100MCP de destino (comsessao: browsers)ONDE A SESSAO DO DESTINO MORRE (TODAS SILENCIOSAMENTE)5 min paradaDELETE da sessao; a janela do browsersomequalquer erro na chamadaevict — inclusive EGRESS_TIMEOUT acimade 60 sdeploy / restarto onClose manda DELETE em todas404 do destinonovo initialize; a chamada passa, oestado volta do zero, o agente nao eavisado

O que quebra hoje, por ordem de impacto

MCP de destinoImpactoPor que
MCP que so fala 2026-07-28 (o do MyPanel)MCP inteiro: 0 tools, toda chamada falhao cliente v1 1.30.1 so conhece ate 2025-11-25
MCP com sessao (browsers)funciona ate: 5 min parado, 1 chamada acima de 60 s, 1 erro HTTP, deploy — e mistura conversas
MCP SSE legado (/sse)MCP inteiro: nao conectao proxy marca 'not spoken'
MCP so de stdio (REA) via pontedepende da ponte: hoje fora do ar (503)as 4 falhas de producao tem a assinatura da ponte sem reescrita de id
Empresa A x empresa Bcatalogo de MCP e global (seguranca, nao 'nao funciona')

04O proxy de MCP depois

O que a correcao entrega — e o defeito que continua aberto

HOJEa sessao e por (chave, projeto)conversa Aconversa Bmesma janelado browserduas conversas da mesma chavedividem a MESMA sessao, semaviso quando ela morre sozinhaDEPOISo escopo cresce por dentro do ja autorizadoconversa Aconversa Bsessao Asessao BMcp-Session-Id e so ENTRADA,nunca emitido. Sem o header,o escopo e o de hoje: sem regressaoator e projeto seguem do tokenO DEFEITO QUE CONTINUA ABERTO: QUANDO O STREAM MORRE, O POOL FICA ENVENENADOGET /sse caiidle timeout do LB, rede,deployonerror so logaa entrada do pool nunca saiEGRESS_TIMEOUT 5 mine o TTL de 30 min RENOVA acada tentativaso se cura para quemfica quietoescritas executam 2x nodestinoProva: r3-lab-streamdead.jsonl — pool=1 sem evict, 2 tools/call de verdade no destino.Fix: marcar a conexao quando o stream cai e evict + retry so-em-leitura, apenas quando transport = sse.

O que a correcao entrega

SSE legado se cura sozinho quando a sessao cai

A proxima chamada da conversa refaz o handshake (GET /sse novo) em vez de repetir o mesmo erro por 30 min. Em LEITURA a chamada e repetida na sessao nova; em ESCRITA nao (o efeito pode ter ocorrido) — e nos dois casos o resultado leva o aviso pt-BR de sessao reiniciada, igual ao Streamable HTTP.

Prova: 2 testes novos contra upstream SSE legado REAL (v1 SSEServerTransport) com dropSessions(): reconexao (inits 1 -> 2) e http_status em vez de invalid_response.

O erro que chega e o status real do upstream

McpUpstreamError com problem http_status e o codigo, mensagem citando HTTP 400/404/410, em vez de 'The MCP server sent an invalid JSON-RPC response'.

Prova: Red-check: desligando so o ssePostRefusalStatus, os 2 testes novos falham e os outros 6 do arquivo passam.

401/403 no SSE continuam NAO sendo sessao morta

O cliente sobrevive a eles: uma credencial trocada no cadastro nao derruba a janela do MCP nem dispara handshake desnecessario. So 400/404/410 contam.

Prova: Faixa estreita, deliberada.

O outro lado do ciclo de vida: quando o STREAM morre, o pool fica envenenado

O GET /sse morre (idle timeout do LB, rede, deploy). O client.onerror recebe o SseError e so loga: a entrada do pool NUNCA sai. Toda chamada daquele escopo cai em EGRESS_TIMEOUT por 5 min, e o updateAgeOnGet do LeasePool RENOVA o TTL de 30 min a cada tentativa — entao so se cura para quem ficar quieto.

Consequencia: Tools de ESCRITA executam de verdade no destino enquanto o agente ve 'o destino nao respondeu', e a chamada seguinte executa de novo. Execucao duplicada com o agente mal informado.

Prova: r3-lab-streamdead.jsonl: pool=1 sem evict, 2 tools/call de verdade no destino.

Fix: Marcar a conexao quando o stream cai; tratar EgressTimeoutError/SseError como sessao morta SO quando transport e 'sse' (o Streamable HTTP mantem a regra atual e o teste que a trava continua verde); evict + retry so-em-leitura + onSessionRestarted. Cobrir tambem a chamada que estava em voo quando o stream caiu.

A regra de quem manda na sessao

QuandoRegra
antesA sessao e por (chave, projeto). Duas conversas da mesma chave dividem a mesma janela do browser. Nao existe sessao de quem chama, porque o gateway e stateless.
depoisO Mcp-Session-Id entra como ENTRADA OPCIONAL e nunca e emitido. O gateway continua stateless (ADR-011) e sem o header o escopo e o de hoje. Com o header, o escopo do pool passa a ser a conversa — sem escalada, porque ator e projeto continuam vindo do token e do header.
prova2 testes em mcp-transport.test.ts: o header e so entrada (initialize nao o devolve, duas conversas chamam) e valor malformado e ignorado.

As regras de seguranca que a correcao adoptou

RegraPor que
Retry de 404 so em chamada de leiturao HTTP nao distingue chamada processada de nao processada; repetir uma escrita pode duplicar efeito. Em escrita so o aviso.
401/403 nunca sao sessao mortao cliente sobrevive a eles; repetir o handshake nao conserta credencial errada.
O Mcp-Session-Id so entra, nunca saiator e projeto continuam vindo do token e do header — o id nao concede nada novo.
Cache do catalogo com chave por organizacaodepois da migration por empresa, o '*' global faria duas empresas lerem o MESMO objeto cacheado.
Credencial so atravessa a origem ja autorizadanextHop compara por origin, e origin ignora porta padrao — o B2 corrige isso.

05O que impede de dizer que esta pronto

12 bloqueios abertos. 3 criticos. O status real do trabalho e BLOQUEADO, nao pronto: os gates verdes provam que os testes existentes nao regrediram, nao que as revisoes aprovaram.

critico
Nenhuma linha da app Render foi escrita

O repo PedroPaduelo/render tem 1 commit e um unico README.md de 129 bytes. O proprio desenho diz: 'Isto e planta, nao execucao.' O dono pediu a aplicacao, nao a planta.

Proximo passo: Responder as 5 decisoes D1-D4 e D17 e despachar P-1..P14 em worktrees do sandbox render

critico
Defeto aberto e PROVADO no proxy de MCP (stream do SSE que morre)

Quando o stream GET /sse morre, a entrada do pool nunca sai. Toda chamada cai em EGRESS_TIMEOUT por 5 min ate o TTL de 30 min, que cada tentativa RENOVA. Tools de ESCRITA executam de verdade no destino enquanto o agente ve 'o destino nao respondeu', e a chamada seguinte executa de novo.

Proximo passo: Marcar a conexao quando o stream cai (hoje o client.onerror so loga), tratar EgressTimeoutError/SseError como sessao morta so quando transport e 'sse', evict + retry so-em-leitura + onSessionRestarted

critico
Seguranca multiempresa B1 — regressao INTRODUZIDA pelo trabalho

orgVisible() devolve true para organizationId null (correto para leitura) e a regra foi propagada para as ESCRITAS. PATCH, DELETE e as DUAS rotas de credencial nao conferem posse. Qualquer usuario de qualquer empresa pode reescrever a URL de um MCP de plataforma ou de outra empresa, trocar/apagar a credencial cifrada e apagar a linha.

Proximo passo: Exigir posse (organizationId igual) em todo write e nas duas rotas de credencial; passar scope para setBearerToken/clearSecrets; teste fixando que empresa A nao escreve na linha da B. Fechar ANTES de qualquer deploy.

alto
Credencial vazada em redirect B2 — nextHop() compara por origin

origin ignora porta padrao. Redirect de https://host/mcp para https://host:80/mcp mantem o Authorization com uma origem que a politica nao considera igual. O host continua revalidado (SSRF nao abre), mas a garantia de credencial esta furada.

Proximo passo: Comparar por host e porta efetiva, com teste de redirect para porta padrao e nao-padrao

alto
Erro mentiroso no HANDSHAKE (so tools/call foi corrigido)

O commit 1a67c15 corrigiu tools/call, mas quando o POST recusado e o da sonda/initialize o SDK embrulha o Error e a classificacao cai em 'invalid_response' ANTES do extrator de status HTTP. Voce ve 'resposta invalida' quando o destino recusou com um HTTP claro.

Proximo passo: Percorrer a cadeia cause (como egressCauseOf ja faz) e chamar o extrator antes do ramo SdkError; teste de recusa 400 no initialize

alto
Nada foi para a main, e voce pediu merge na main

A branch fix/mcp-proxy-sessoes (9 commits, head 1a67c15) NAO existe no GitHub — a API devolve 404 para a ref. Existe so no worktree local do sandbox, que expira em 2026-10-16. As branches feat/prompts-agente e feat/roadmap-gantt tambem so estao locais.

Proximo passo: Com o seu aval: push da branch e merge na main, e so entao o deployments_trigger. Hoje NAO ha nada para deployar.

alto
AGENTPACK_CONTA_URL quebrado em PRODUCAO, para todo usuario

O bundle do agentpack-frontend-ws embute o sandbox morto https://sb-conta-nommand-app.mp.serendiped.com. A Conta de producao e https://conta.mp.serendiped.com. Quebra Minha Conta, Gerenciar na Conta, o aviso de laco de SSO e o fallback da barra. A decisao D16 e 'sim, e uma env e um rebuild' e nada foi feito.

Proximo passo: Sua env AGENTPACK_CONTA_URL=https://conta.mp.serendiped.com + rebuild do agentpack-frontend-ws. Escrita em producao, proibida para os agentes.

medio
Os 4 pontos que derrubam o AgentPack no dia da remocao nao foram preparados

toolError mora em tools/render/common.ts e e usado por mcp/tool-call.ts e mcp/proxy-call.ts para TODA tool; appBaseUrl mora em lib/render-view-url.ts e e usado por task-decision.service.ts; as 3 tools project_* moram no registro do Render; e as 2 chaves de rate-limit.ts:87-88 derrubam o boot se as rotas sumirem.

Proximo passo: Executar P-1 e P-2 (que sao no AgentPack e nao dependem de nada) antes de qualquer remocao

medio
Status da entrega estava reportado como 'pronto' com 5 bloqueios abertos

impl.json marcava status 'done' e falhas_novas [], enquanto as 3 revisoes da rodada 3 estao com verdict 'fix' e 5 bloqueios abertos no mesmo head. 'Pronto' ali significava apenas que os testes existentes continuavam verdes.

Proximo passo: Este relatorio abre pelos bloqueios, nao pelos gates verdes. O status real e BLOQUEADO.

medio
'Renner' nao foi esclarecido

Voce disse: 'nao existe a sandbox para o Renner, voce vai ter que criar... nao existe um repository Git para ele, voce vai ter que criar. Privado, publico nao, privado.' Se 'Renner' e o Render: sandbox e repo privado JA FORAM criados (sb-render, PedroPaduelo/render privado) — o que falta e o codigo. Se 'Renner' e uma pessoa, nada foi criado para ela.

Proximo passo: Confirmar se Renner = Render ou uma pessoa. Se for pessoa, criar sandbox + repo privado e atualizar o escopo.

medio
Riscos sem dono e sem prazo

B6 (orgId no actor do token de preview + NOT NULL em agent_keys.organization_id) ficou 'de proposito' de fora, sem dono. As 3 falhas pre-existentes de shutdown.test.ts tambem estao sem dono. Sem teste dedicado tambem para 500 no SSE (que nao e sessao morta).

Proximo passo: Nomear dono e prazo, ou registrar aceite formal do risco

baixo
Runbook de deploy do backend do MCP nao existe

O runbook que existe e o da app Render. Falta o de deploy/rollback da correcao de MCP no agentpack-backend-ws, e o efeito da migration 20261013090000 no banco de producao.

Proximo passo: Escrever: deployments_trigger, conferencia por hash de bundle, rollback = deployments_rollback, e o passo da migration

Nao existe a sandbox para o Renner, voce vai ter que criar. Nao existe um repository Git para ele, voce vai ter que criar. Privado, publico nao, privado.

Renner = Render. Entao ja esta feito: sandbox 'render' criada em 2026-10-13 (20 GB) e repo PedroPaduelo/render PRIVADO. O que falta e o codigo, nao a sandbox nem o repo.

Preciso da sua palavra: Preciso da sua palavra: Renner e o Render ou uma pessoa?

06Suas 17 decisoes

5 delas travam um pacote: sem a resposta, nenhum agente pode comecar. Todas as 17 tem recomendacao do desenho.

As que travam

D1trava P1
Projetos: a app Render guarda o id do projeto do AgentPack num espelho local, ou tem projetos proprios?
RecomendacaoEspelho local com o MESMO id (render_projects), alimentado por migration + webhook assinado + reconciliador idempotente.

Por que: As 4 tabelas do Render tem FK project_id e toda operacao passa por requireProject: sem esta decisao nenhuma tela, mapa, biblioteca de projeto ou porte abre. Espelhar preserva os ids que os URLs, a key da decisao de upgrade e os designSystemId ja carregam. Ler por API a cada chamada transforma uma transacao SERIALIZABLE em duas e quebra agente sem rede.

O que custa: A cascata e o portao de lixeira passam a ser espelho: o purge precisa virar evento (webhook + reconciliador) e o AgentPack precisa de um contrato de purga.

D2trava P7
Portao do upgrade de design system: a app nova aprova como, se hoje o gate le task_decisions do AgentPack?
RecomendacaoTabela propria (render_approvals), com a key render-ds-upgrade-<8 do DS>-<from>-to-v<to>-r<cop>, os rotulos Aplicar a atualizacao / Manter a versao atual, e a semantica de uma decisao aprovada autorizar UMA transicao. A tela mostra o diff e as pins.

Por que: Consultar o AgentPack por API e exatamente o acoplamento que a extracao quer eliminar, e a alternativa de so pessoa logada enfraquece a garantia de que um agente nunca se aprova. O caminho humano (REST) ja existe e nao precisa de tabela.

O que custa: A pergunta nova e se voce aceita a TELA de decisao nova dentro da app Render. Se nao, o caminho do agente volta ao AgentPack, ou a tool exige approvedByHuman e responde APPROVAL_REQUIRED.

D3trava P4b
Catalogo global (project_id NULL, hoje de plataforma e visivel por todas as empresas): vira por empresa, some, ou continua global?
RecomendacaoVira escopo de empresa: organization_id obrigatorio nas linhas globais, com backfill para uma empresa decidida. Virou o pacote P4b.

Por que: A regra sua e que cada app guarda so os proprios recursos, e hoje qualquer usuario de qualquer empresa escreve no catalogo global (alcance platform). Manter global leva um vazamento multiempresa para a app nova. Some e demais: as bibliotecas globais sao o espelho de onde os projetos herdam.

O que custa: Mudanca de dado, indice, consulta e politica: 3 indices parciais reescritos, visibleProjectsWhere/activeOwnerWhere por organizacao, GlobalWriteReach passando de platform para org, e a assinatura de readLibrary/writeLibrary recebendo a organizacao ativa (35 chamadores).

D4trava P3
Chaves de agente: a app Render emite as proprias apk_* ou valida as do AgentPack?
RecomendacaoProprias, com kind project (projectIds; revoga quando o criador sai da empresa) e kind admin (chave DA empresa; o criador sair, perder o papel ou ser desativado nao derruba).

Por que: E a unica forma de implementar a sua regra — contrato encerrado suspende as chaves da empresa, recontrato reativa as MESMAS chaves, saida de membro revoga so as pessoais — num app que controle as chaves. A suspensao ja esta implementada e testada no LB (LB-ORG-SUSP-01) e pode ser copiada de la.

O que custa: Cliente OIDC proprio 'render', claim apps[render], e um CONTA_PROVISIONING_SECRET novo por app (e o que identifica o app.contract.cancelled desta app). Acao sua fora do painel.

D17trava P3
Criador desativado x chave admin da empresa: herda o comportamento do AgentPack?
RecomendacaoHerda, com uma regra a mais: o criador desativado NAO pode mais gerenciar chaves, mas a chave admin da empresa continua valendo — e a razao de ela ser da empresa.

Por que: No AgentPack, AgentKey.createdBy tem onDelete SetNull e authenticateAgentKey nao consulta o estado do criador: desativar o criador nao derruba a chave admin. E a semantica correta para uma chave que e da empresa e nao da pessoa.

O que custa: Se preferir que desativar o criador DERRUBE a chave admin, e checagem nova — authenticateAgentKey passa a consultar o estado do criador — e muda o contrato da D4.

As que ja tem recomendacao fechada

D5
Nomes das tools MCP: manter agentpack_render_* ou renomear para render_* na app nova?
RecomendacaoManter agentpack_render_* (nome de wire) e os toolsets render / render-admin.

Por que: Renomear quebra 7 skills built-in, a skill agentpack-task-execution, docs geradas, prompts e configs de agente ja gravados. O prefixo e de wire: o codigo dos handlers nao o ve (defineTool grava render_screen_list e o registro prefixa com BUILTIN_TOOL_PREFIX). A app Render mantem o prefixo no gateway proprio.

Custo/ressalva: Nenhum. A diferenca e so de rotulo de API.

D6
Na transicao, o AgentPack cadastra o MCP da app Render no proxy dele?
RecomendacaoSim, mas no corte (fase B), com toolPrefix agentpack_render — e so DEPOIS do P-2. Agentes passam a ter uma URL so.

Por que: loadProxiedCatalog descarta nome que colide com built-in: enquanto o registro do AgentPack ainda tiver RENDER_TOOLS, a ponte nao publica nada. E mecanismo de virada, nao de convivencia. Com o prefixo, as tools chegam ao agente com exatamente os nomes de hoje.

Custo/ressalva: Tres ressalvas aceitas: tool proxied recebe escopo write e nao render:write; a identidade do agente nao atravessa (o Render ve a chave da configuracao do MCP, nao a do agente); toda chamada proxied vira linha de auditoria como escrita. Antes de cadastrar, o McpServer precisa de organizationId (achado C4).

D7
Skills agentpack-render-*: ficam no AgentPack ou vao para a app Render?
RecomendacaoFicam no AgentPack, sem mudanca na fase 1.

Por que: Skills sao recurso do AgentPack e o gate npm run check:skills valida as tools citadas contra o catalogo — que, com a ponte ativa, continua publicando agentpack_render_*. A app nova publica os seus docs/mcp/tools.md e llms-full.txt.

Custo/ressalva: Se a ponte for desativada e o registro do Render sair do AgentPack, as 7 skills passam a citar tools inexistentes e o check:skills quebra: nesse momento precisam ser reescritas ou aposentadas.

D8
Nomes dos servicos e dominios no MyPanel?
Recomendacaorender-backend-ws e render-frontend-ws em workspace_nommand, dominios render-v0.mp.serendiped.com e render-v0-api.mp.serendiped.com, mais render-shot-ws (4500, 1 GB, sem dominio).

Por que: Segue o padrao dos vizinhos (agentpack-backend-ws / agentpack-frontend-ws / agentpack-v0 / agentpack-v0-api), os nomes de container sao globais no painel e nao colidem com o sandbox sb-render, e o sufixo v0 deixa o dominio curto para quando a versao estavel sair.

Custo/ressalva: Fora do workspace_nommand nao ha ganho e quebra o pregao dos bancos de producao.

D9
shot/: entra em producao na app nova ou continua desligado como hoje?
RecomendacaoEntra como servico proprio (render-shot-ws, 1 GB, SHOT_ALLOW_ORIGINS do frontend novo), mas e a ULTIMA coisa a subir.

Por que: Hoje nao existe em producao e a captura esta provavelmente quebrada desde 2026-09-29 (o shot grava sessionStorage agentpack:auth-token, que o frontend nao le mais desde 7ac8e39, e /render/preview/** esta atras do RequireAuth: o Chromium cai no SSO). Ligar entrega as duas tools de screenshot que hoje devolvem so a URL.

Custo/ressalva: 1 GB e um servico a mais. Deixar desligado e aceitavel e mais barato.

D10
@nomad/ui: a app nova entra na v1.13.5 (AgentPack e Motor) ou na v1.13.7 (LB e Conta)?
Recomendacaov1.13.5, com o spec git+https://github.com/PedroPaduelo/nomad-ui.git#v1.13.5 e o lock resolvendo o commit 19063f9. NUNCA #main.

Por que: Mesmo preset de eslint e tsconfig do AgentPack — tres arquivos do Render estao no teto do lint, mudar o preset estoura o gate — e mesmo check-lock no prebuild.

Custo/ressalva: A v1.13.7 difere num componente de teclado; subir depois e bump de uma linha. A main do nomad-ui tem 1 arquivo e qualquer spec sem tag instala nada.

D11
Banco da app nova: Postgres proprio em databases_prod? E o DB_CONNECTION_LIMIT 1000 vale para ela?
RecomendacaoPostgres proprio em databases_prod, com max_connections ACIMA de 1000, e DB_CONNECTION_LIMIT 1000.

Por que: Banco separado e o que torna possivel matar o Render no AgentPack com uma migration de drop sem tocar em mais nada. O padrao do Postgres e max_connections 100 e o pool do Prisma vence o que vier na URL.

Custo/ressalva: Redis opcional: o Render so usa os contadores do rate limit e sem REDIS_URL o plugin conta por instancia.

D12
autoDeploy dos servicos novos: ligado ou desligado?
RecomendacaoDesligado, e nunca mais ligar. Publicacao e deployments_trigger, decisao sua.

Por que: Os 9 servicos do workspace_nommand estao com autoDeploy true, mas o historico mostra deploy manual (o backend do AgentPack teve 1 deploy entre 10-03 e 10-11 com 18 commits na main). Merge na main nao deve publicar nada sem um trigger explicito seu — que e exatamente o que voce pediu.

Custo/ressalva: Nenhum. E o comportamento que voce pediu.

D13
Migracao dos dados: qual janela de congelamento, e o que fazer com projetos na lixeira?
RecomendacaoCongelar a escrita do Render no AgentPack (feature flag, 503 RENDER_FROZEN), repetir a copia, e so entao cortar. Projetos na lixeira sao copiados com o mesmo deleted_at e so aparecem depois do restore.

Por que: As escritas do Render sao transacoes SERIALIZABLE de REST e MCP e um agente escreve a qualquer hora; sem congelar, quem escrever as 3h da manha perde a tela. Congelar e curto e declarado.

Custo/ressalva: O script e so-insert contra banco novo: o rollback e descartar o banco novo (e o volume) e reabrir a escrita no AgentPack.

D14
O catalogo global legado (/api/library/:kind e /api/designs global) vai junto?
RecomendacaoVai, mas escopado por empresa (a D3).

Por que: As rotas legadas sao o que o frontend atual usa (3 modais, o guarda de rota) e sao o caminho de heranca global -> projeto; deixar de fora quebra a autoria. O que nao pode e continuar como catalogo de plataforma de todas as empresas.

Custo/ressalva: Depende da D3 ser respondida.

D15
Corrigir a captura de preview quebrada entra nesta frente?
RecomendacaoSim, com cookie httpOnly de desafio one-shot (e nao sessionStorage).

Por que: E correcao de credencial e de superficie de ataque, nao feature: sem ela as duas tools de screenshot nao funcionam em lugar nenhum, porque o frontend nao le mais a chave que o shot grava. E a pagina de preview executa o motor do Render: com sessionStorage, qualquer XSS le o token.

Custo/ressalva: Um gancho no cliente HTTP (getToken), a chave de storage certa no shot, e o RequireAuth do preview redesenhado. Vem no pacote P12.

D16
Corrigir junto o AGENTPACK_CONTA_URL do frontend do AgentPack (env no painel + rebuild)?
RecomendacaoSim. Uma env no painel e um rebuild.

Por que: O bug ja esta em PRODUCAO para todo usuario do AgentPack: Minha Conta, Gerenciar na Conta, o aviso de laco de SSO e o fallback da barra apontam para um sandbox morto. A app nova ja nasce com o build arg certo (RENDER_CONTA_URL) desde o primeiro deploy.

Custo/ressalva: Escrita em producao, que os agentes tem proibida. Precisa do seu go.

07Os 18 pacotes da app Render

Cada pacote e do tamanho de um agente. Os dois primeiros sao no AgentPack (preparo) e nao dependem de nada — sao o que evita derrubar o /mcp no dia da remocao.

#PacoteOndeDepende deEstado
P-1Preparo do AgentPack: mover toolErrorAgentPack—nao feito
derruba o /mcp inteiro se a pasta Render for apagada antes disso
P-2organizationId em McpServer + normalizacao do prefixo upstreamAgentPack—nao feito
sem isso a ponte publica agentpack_render_agentpack_render_*
P0Nucleo do backend da app RenderRender—nao feito
esqueleto Fastify, config, Prisma, erros, plugins, health, Dockerfiles, gates
P1Banco do Render: schema, migration e espelhos da ContaRenderP0nao feito
TRAVA D1
P2Contratos do Render (zod, JSON Schema, typegen, seguranca)RenderP0, P1nao feito
P3Identidade: OIDC render, suspensao por contrato, chaves apk_*, token de previewRenderP0, P1nao feito
TRAVA D4 + D17
P4Dominio do Render no backend (services e lib)RenderP2, P3nao feito
P4bEscopo de empresa do catalogoRenderP3, P4nao feito
TRAVA D3
P5Rotas REST, schemas zod e serializers do RenderRenderP4bnao feito
47 rotas
P6Tools MCP do Render e gateway /mcp proprioRenderP5nao feito
59 tools
P7Portao de upgrade, aprovacoes e sincronia de projetosRenderP6nao feito
TRAVA D2
P8Casca do frontend: Vite, Tailwind, @nomad/ui, TopBar Nomad, shell, nginxRenderP0, P6nao feito
aqui o @nomad/ui v1.13.5 entra fixado
P9Motor do Render no frontend (engine, primitivas, canvas, contrato gerado)RenderP8, P2nao feito
P10Camada de dados e editor de tela do Render no frontendRenderP6, P8nao feito
P11Telas do Render: raiz, Studio, compartilhados, telas de projeto, previews e rotasRenderP9, P10nao feito
P12shot/ como servico da app + caminho de credencial do previewRenderP11, P3nao feito
cookie httpOnly, nao sessionStorage
P13Testes do Render migrados, cobertura, docs e gatesRenderP5, P6, P9, P10, P11nao feito
P14Script de migracao dos dados de producao e runbook de corteRenderP13, P7nao feito
so depois das travas

08Proximos passos, em ordem

O que fazer em cada etapa, quem faz e por que nessa ordem. O passo 3 e o unico que so voce pode executar.

1Construir o Render no sandbox novo

Voce responde as 5 travas (D1, D2, D3, D4, D17) e os agentes comecam a escrever codigo no sandbox 'render' (20 GB), em worktrees, commitando no PedroPaduelo/render.

Por que nesta ordem: E o pedido principal e o que nao existe. Hoje ha desenho, nao aplicacao. O repo ja e privado e o sandbox ja foi criado — falta o codigo.

  • Responder D1 (projeto/espelho), D2 (portao de upgrade), D3 (catalogo por empresa), D4 (chaves proprias) e D17 (criador desativado x chave admin)
  • Esclarecer se 'Renner' e o Render ou uma pessoa
  • Despachar P-1 e P-2 no AgentPack (nao dependem de nada e evitam derrubar o /mcp na remocao)
  • Despachar P0..P14 em worktrees do sandbox render, na ordem das dependencias
  • Fixar '@nomad/ui' em git+https://github.com/PedroPaduelo/nomad-ui.git#v1.13.5 e conferir npx npm@10.9.4 ci --dry-run

Quem faz: agentes em worktrees

2Fechar os 5 bloqueios da revisao e Só entao mergir a correcao do MCP

A branch fix/mcp-proxy-sessoes (9 commits, head 1a67c15) esta so no worktree local. Antes do push, os 5 bloqueios da rodada 3 precisam cair.

Por que nesta ordem: Ha um defeito provado de ciclo de vida (stream do SSE que morre) e uma regressao de seguranca multiempresa introduzida pelo proprio trabalho (B1). Mergir agora publicaria pior do que o que existe.

  • B1: exigir posse em todo write e nas duas rotas de credencial; teste fixando o isolamento entre empresas
  • B2: nextHop compara por host e porta efetiva, com teste de redirect
  • Correcao 1: marcar a conexao quando o stream do SSE cai; evict + retry so-em-leitura + onSessionRestarted
  • Concorrencia 2: classificar o erro do handshake percorrendo a cadeia cause, antes do ramo SdkError
  • Re-rodar as 3 lentes (correcao, concorrencia, seguranca) ate verdict approve
  • Levar o ADR-0015 (sessao por conversa) para o seu aceite antes do deploy
  • Push da branch e merge na main, no estilo do historico do repo

Quem faz: agentes, com o seu aval para push e merge

3Runbook de deploy — e so entao o trigger

Nenhum passo publica nada sozinho: autoDeploy desligado nos servicos novos. A publicacao e deployments_trigger, uma decisao sua.

Por que nesta ordem: Voce pediu: deixa pronto, mergia para a main, e quando tiver tudo pronto me fala para a gente dar ou nao o trigger no deploy. Esta e a parte que so voce faz.

  • Servico novo: sourceType github, repo PedroPaduelo/render, branch main, autoDeploy DESLIGADO, limits e volume do runbook
  • Backend: 4000, 1024 MB, volume render-prod-data em /data, dominio render-v0-api.mp.serendiped.com com SSL
  • Frontend: 8080, 256 MB, dominio render-v0.mp.serendiped.com, e RENDER_CONTA_URL=https://conta.mp.serendiped.com OBRIGATORIO no build
  • Conferir /health/live e /health/ready do backend, /healthz e o 401 de /api/auth/me no frontend
  • shot/ por ultimo, so quando a credencial de preview estiver corrigida
  • So entao: deployments_trigger. Confirmar pelo hash do build.

Quem faz: voce, com o runbook do desenho em maos

09Runbook de producao

Nada foi criado no painel. Isto e runbook, nao execucao.

As envs vao com segredo via env_vars_create com isSecret. Nenhum valor de segredo aparece neste relatorio.

Pre-requisito seu, fora do painel

  • Criar na Conta Nommand o cliente OIDC 'render' (redirect https://render-v0.mp.serendiped.com/auth/callback) e um CONTA_PROVISIONING_SECRET novo e exclusivo
  • Registrar 'render' no AppSwitcher e liberar o papel apps[render] na empresa
ServicoPortaMemoriaVolumeDominio
render-backend-ws40001024 MBrender-prod-data -> /datarender-v0-api.mp.serendiped.com
render-frontend-ws8080256 MB-render-v0.mp.serendiped.com
render-shot-ws45001024 MB-nenhum (opcional, por ultimo)

Postgres proprio em databases_prod, max_connections acima de 1000, DB_CONNECTION_LIMIT 1000. Nenhum banco foi criado.

O corte. Remover RENDER_TOOLS do registro do AgentPack, cadastrar o MCP https://render-v0-api.mp.serendiped.com/mcp com toolPrefix agentpack_render, e conferir os 59 nomes agentpack_render_* em tools/list.