prometeu-studio/discussion/workflow/agendas/AGD-0059-multi-frontend-remove-pbs-branches.md
2026-07-15 11:22:38 +01:00

165 lines
13 KiB
Markdown

---
id: AGD-0059
ticket: multi-frontend-remove-pbs-branches
title: Generalizar o contrato LSP/editorial para frontends
status: accepted
created: 2026-07-15
resolved:
decision:
tags: [compiler, compiler-general, compiler-pbs, studio, frontend, coupling, multi-frontend]
---
# Agenda - Generalizar o contrato LSP/editorial para frontends
## Pain
Domain owner: `compiler/general`, com impacto em `studio` e `compiler/pbs`.
O PBS ja esta majoritariamente centrado no proprio frontend. A auditoria inicial nao confirmou um problema amplo de codigo comum decidindo comportamento por PBS.
O acoplamento que ainda importa e mais especifico: o `CompilerLanguageServiceBridge` do LSP usa diretamente classes do frontend PBS para completion, hover, signature help, semantic tokens e leitura editorial. Isso impede que outro frontend plugado no registry ofereca LSP/editor assistance sem repetir ou bifurcar esse caminho.
## Context
PBS e a linguagem default do produto hoje. Usar PBS como fallback quando o usuario nao escolhe linguagem e valido e deve continuar permitido. Isso inclui defaults de criacao de projeto e bootstrap de registry/composition root enquanto PBS for o unico frontend concreto.
A verificacao local mostrou este estado:
- referencias PBS dentro de `prometeu-compiler/frontends/prometeu-frontend-pbs/**` sao internas ao frontend e nao sao problema;
- testes, fixtures `.pbs`, templates PBS, semantic keys PBS e registro da extensao VS Code para `.pbs` sao referencias esperadas;
- `ProjectLanguageCatalogService` ja constroi templates a partir de `FrontendRegistryService.listProviders()`;
- `ProjectCatalogService` ainda usa `"pbs"` em overloads simples de `createProject(...)`, mas isso representa default/fallback e nao deve ser tratado como violacao;
- `FrontendRegistryService` registra `PBSFrontendProvider` como default concreto, o que pertence ao bootstrap/composition root atual;
- `CompilerLanguageServiceBridge` ainda importa `PBSFrontendLanguageService`, `PBSFrontendPhaseService`, `p.studio.compiler.pbs.semantics.*` e tipos AST PBS diretamente.
Portanto a agenda deve deixar de ser uma busca generica por `"pbs"` e passar a discutir qual contrato LSP/editorial generico os frontends devem implementar, em etapas, para que PBS seja apenas um provider desse contrato.
## Open Questions
- [x] Qual e o menor contrato editorial generico que um frontend precisa expor para o LSP v1 dentro do `languageService()` opcional: semantic tokens, completion, hover e signature help em uma superficie agregada ou como capacidades internas declaraveis?
- Resposta: manter `FrontendProvider.languageService()` como superficie opcional agregada; dentro dela, expor capacidades editoriais pequenas e opcionais para semantic tokens, completion, hover e signature help.
- [x] O contrato deve viver em `prometeu-frontend-api`, `prometeu-compiler-core`, ou em um modulo especifico de language services compartilhado?
- Resposta: o contrato generico deve viver em `prometeu-frontend-api`, porque e a fronteira entre frontends e consumidores comuns. O frontend nao deve depender de `prometeu-lsp`, e tipos editoriais nao devem ser empurrados para `compiler-core` sem necessidade.
- [x] O LSP deve consumir apenas tipos genericos de frontend, ou pode manter um adapter PBS temporario enquanto as interfaces sao extraidas em etapas?
- Resposta: o estado final deve consumir apenas tipos genericos de frontend; adapters PBS temporarios sao aceitaveis apenas como migracao por capacidade.
- [x] Como o pipeline deve fornecer AST/snapshot/editorial context sem expor `PbsAst.File` e `PBSFrontendPhaseService.semanticReadSurface(...)` ao LSP?
- Resposta: o LSP deve pedir capacidades ao language service do provider selecionado. O provider/frontend fica responsavel por produzir ou consumir o snapshot editorial necessario, sem expor AST PBS ou semantic read surface PBS ao caminho comum do LSP.
- [x] Como representar tipos hoje PBS-specific, como `PbsEditorialCompletionCandidate`, `PbsEditorialResolvedSymbol`, `PbsEditorialSignatureHelp` e `PbsEditorialSymbolKind`, em modelos genericos sem perder informacao necessaria?
- Resposta: criar modelos genericos pequenos, como `FrontendCompletionCandidate`, `FrontendHover`, `FrontendSignatureHelp`, `FrontendSignature`, `FrontendSymbolKind` e, se necessario, `FrontendDocumentation`. PBS mapeia seus tipos internos para esses modelos.
- [x] Quais capacidades devem ser opcionais por frontend para permitir frontends compile-only sem quebrar o LSP?
- Resposta: todas as capacidades editoriais sao opcionais. `compiler()` continua obrigatorio; `languageService()` continua opcional; cada feature editorial deve ter fallback deterministico quando ausente.
- [x] Quais referencias PBS devem ser registradas como excecoes permanentes ou temporarias: default/fallback, composition root, testes, templates, fixtures, extensao VS Code e frontend PBS interno?
- Resposta: sao permitidos frontend PBS interno, testes PBS, fixtures `.pbs`, templates PBS, VS Code `.pbs`, semantic keys PBS, PBS como default/fallback quando o usuario nao escolhe linguagem e bootstrap/composition root enquanto PBS for o frontend concreto default. Nao sao permitidos imports PBS no LSP comum, instanciacao PBS em common compiler/build/studio fora de provider/composition root, nem fallback PBS para `languageId` desconhecido.
## Options
### Option A - Interface editorial generica em uma etapa
- **Approach:** definir de uma vez uma interface generica para semantic tokens, completion, hover, signature help, documentos editoriais e modelos de retorno; migrar o LSP para consumir apenas essa interface.
- **Pro:** remove o acoplamento PBS do LSP em um unico corte conceitual.
- **Con:** alto risco de abstrair demais antes de existir um segundo frontend real; pode forcar modelos genericos grandes e instaveis.
- **Maintainability:** boa se o contrato sair correto, mas fragil se a primeira versao tentar cobrir casos ainda desconhecidos.
### Option B - Extracao incremental por capacidades LSP
- **Approach:** extrair contratos genericos em etapas, comecando pelas capacidades mais estaveis: semantic presentation/tokens, depois completion, hover e signature help. Cada etapa move um conjunto de tipos PBS-specific para modelos de frontend/language-service genericos.
- **Pro:** reduz risco, preserva o comportamento PBS existente e permite validar cada fronteira com testes focados.
- **Con:** durante a transicao o LSP pode manter alguns adapters PBS temporarios.
- **Maintainability:** forte, porque cada capacidade ganha contrato proprio e a arquitetura aprende com o codigo existente antes de generalizar tudo.
### Option C - Manter LSP v1 PBS-specific por enquanto
- **Approach:** reconhecer que PBS e o unico frontend concreto com editor assistance hoje e adiar a generalizacao ate o segundo frontend exigir LSP.
- **Pro:** custo imediato baixo e nenhum risco de abstrair prematuramente.
- **Con:** solidifica o LSP como PBS-specific e aumenta o custo da proxima linguagem; novos frontends compile-only nao terao caminho claro para capacidades editoriais.
- **Maintainability:** aceitavel no curtissimo prazo, fraca para o objetivo multi-frontend.
## Recommendation
Recomendacao fechada: seguir a **Option B - Extracao incremental por capacidades LSP**.
O corte deve reconhecer explicitamente que PBS continua sendo default/fallback. A decisao nao deve tentar eliminar `"pbs"` de defaults, templates ou composition root. O objetivo e remover dependencia PBS do LSP/editorial bridge onde ela impede outro frontend de implementar capacidades equivalentes.
Sequencia recomendada:
1. classificar excecoes permitidas para referencias PBS;
2. definir um contrato generico de capacidades editoriais dentro do `FrontendProvider.languageService()` opcional, sem fragmentar o provider em varias interfaces top-level prematuras;
3. migrar semantic tokens e semantic presentation primeiro, se ainda houver acoplamento alem do spec;
4. migrar completion para modelo generico;
5. migrar hover para modelo generico, incluindo Markdown/documentation e assinatura;
6. migrar signature help para modelo generico;
7. remover o uso direto de `PbsAst`, `PbsEditorial*` e `PBSFrontendPhaseService` do LSP;
8. alimentar a agenda de testes arquiteturais (`AGD-0067`) com uma regra impedindo imports de `p.studio.compiler.pbs` no LSP comum, exceto adapters explicitamente temporarios se a decision permitir.
## Discussion
Esta agenda nao deve ser tratada como uma limpeza textual de `"pbs"`.
As referencias PBS se dividem em categorias diferentes:
- **Permitidas:** frontend PBS interno, testes PBS, fixtures, templates PBS, VS Code `.pbs`, semantic keys PBS, default/fallback de criacao de projeto e bootstrap de provider enquanto PBS for o default concreto.
- **Suspeitas:** codigo comum que instancia ou chama diretamente servicos PBS quando poderia depender de `FrontendProvider`, `FrontendSpec`, capability ou contrato editorial generico.
- **Problema confirmado:** `CompilerLanguageServiceBridge` conhece tipos e servicos PBS diretamente para operar LSP/editor assistance.
O ponto de arquitetura e que o LSP deve projetar capacidades oferecidas pelo frontend selecionado. Ele nao deve saber que o frontend selecionado e PBS para montar completion, hover, signature help ou semantic tokens. PBS deve implementar o contrato; o LSP deve consumir o contrato.
Tambem e importante nao criar uma abstracao grande demais. Frontends podem nascer compile-only e declarar ausencia de capacidades editoriais. O contrato deve permitir capacidades opcionais, com fallback claro no LSP.
Esta agenda deve respeitar as decisions ja consolidadas de provider: `FrontendProvider` continua sendo a unidade comum de registro, `compiler()` continua obrigatorio, `languageService()` continua opcional, e linguagens desconhecidas continuam falhando explicitamente. PBS e fallback valido apenas para ausencia de escolha/default de produto, nao para `languageId` desconhecido.
## Resolution
Consenso de agenda formado em favor de generalizar o contrato LSP/editorial por extracao incremental de capacidades.
PBS permanece como linguagem default e fallback valido quando o usuario nao escolhe linguagem. Esse fallback nao se aplica a `languageId` desconhecido, que deve continuar falhando explicitamente.
O contrato editorial generico deve ser definido em `prometeu-frontend-api`, dentro do modelo de `FrontendProvider.languageService()` opcional ja consolidado. A agenda nao reabre a decisao de provider: `compiler()` continua obrigatorio, `languageService()` continua opcional, e frontends compile-only continuam validos.
O estado final desejado e que o LSP comum consuma modelos editoriais genericos do frontend selecionado, sem importar `p.studio.compiler.pbs.*`, sem conhecer `PbsAst.File`, e sem chamar `PBSFrontendPhaseService.semanticReadSurface(...)` diretamente.
As capacidades devem ser migradas em etapas:
1. semantic tokens e semantic presentation;
2. completion;
3. hover, incluindo Markdown/documentation e assinatura;
4. signature help;
5. remocao dos imports PBS do caminho comum do LSP;
6. repasse da regra de protecao para a agenda de testes arquiteturais (`AGD-0067`).
Adapters PBS temporarios sao aceitaveis apenas durante a migracao de cada capacidade. Eles nao devem virar o contrato permanente do LSP.
As excecoes PBS permitidas sao:
- frontend PBS interno;
- testes PBS;
- fixtures `.pbs`;
- templates PBS;
- registro VS Code para `.pbs`;
- semantic keys PBS;
- PBS como default/fallback quando nao ha escolha explicita de linguagem;
- bootstrap/composition root enquanto PBS for o frontend concreto default.
Referencias PBS nao permitidas no estado final:
- LSP comum importando `p.studio.compiler.pbs.*`;
- common compiler/build/studio instanciando servicos PBS fora de provider/composition root;
- usar PBS como fallback para `languageId` desconhecido.
## Acceptance Signals
- PBS continua funcionando como linguagem default quando o usuario nao escolhe outra.
- Defaults, templates e fixtures PBS nao sao removidos por engano.
- O LSP deixa de importar `p.studio.compiler.pbs.*` em seu caminho comum.
- O provider/frontend language service declara capacidades editoriais de forma generica e opcional.
- PBS implementa essas capacidades sem perder completion, hover, signature help, documentation Markdown ou semantic tokens existentes.
- A agenda de testes arquiteturais cobre pelo menos um provider compile-only ou fake para provar que o LSP comum nao depende de PBS.
## Next Step
Fechar uma decision para:
- declarar PBS como default/fallback permitido;
- listar excecoes permitidas para referencias PBS;
- escolher extracao incremental por capacidades LSP;
- definir os propagation targets para `prometeu-frontend-api`, `prometeu-lsp`, `prometeu-frontend-pbs` e testes arquiteturais.