197 lines
8.7 KiB
Markdown
197 lines
8.7 KiB
Markdown
---
|
|
id: DEC-0032
|
|
ticket: studio-new-lsp-api-and-v1-boundary
|
|
title: Boundary normativo entre lsp-api, lsp-v1 e a extensao VS Code
|
|
status: accepted
|
|
created: 2026-05-05
|
|
accepted: 2026-05-05
|
|
agenda: AGD-0035
|
|
plans: [PLN-0065, PLN-0066, PLN-0067]
|
|
tags: [studio, lsp, vscode, protocol, api, boundary, compiler]
|
|
---
|
|
|
|
## Decision
|
|
|
|
O repositório SHALL reconstruir o stack de linguagem do Studio com separação explícita entre:
|
|
|
|
1. `lsp-api` como boundary interno do Studio;
|
|
2. `lsp-v1` como adapter LSP/JSON-RPC concreto;
|
|
3. `compiler` como owner dos serviços semânticos e de análise consumidos por esse adapter;
|
|
4. `tools/vscode-extension` como cliente externo que continua falando LSP puro via socket TCP.
|
|
|
|
Esta decisão ALSO locks os seguintes pontos:
|
|
|
|
1. `lsp-api` MUST NOT ser espelho do protocolo LSP;
|
|
2. `lsp-api` MUST expor apenas funcionalidades internas realmente consumíveis por outras partes do Studio;
|
|
3. `lsp-api` MAY começar mínima, por exemplo com contratos como `bootServer(project)` e `shutdownServer(project)`;
|
|
4. `lsp-v1` MUST concentrar o servidor LSP concreto, os DTOs de protocolo, o transporte e qualquer dependência de `LSP4J`;
|
|
5. `LSP4J` MUST NOT vazar para fora de `lsp-v1`;
|
|
6. `lsp-v1` MUST consumir serviços existentes de `compiler` em vez de reconstruir pipeline semântico próprio;
|
|
7. o lifecycle do servidor LSP MUST ser associado à abertura e ao fechamento de projeto, não à abertura global do processo Studio;
|
|
8. o atual `lsp-v1` presente hoje no repositório serve apenas como mock de conectividade VS Code ↔ Studio e MUST NOT ser tratado como padrão arquitetural, base estrutural ou referência de implementação do backend definitivo.
|
|
9. a primeira onda de implementação desta decisão SHALL priorizar arquitetura, lifecycle e separação de responsabilidades, mesmo que o comportamento LSP permaneça deliberadamente simples ou "dumb" por um período controlado.
|
|
|
|
## Rationale
|
|
|
|
O stack legado anterior foi removido justamente porque misturava responsabilidades erradas e criou boundaries frágeis entre UI, sessão, semântica e transporte.
|
|
|
|
Ao mesmo tempo, o projeto já tem dois fatos importantes:
|
|
|
|
1. a extensão VS Code já existe e já sabe atuar como cliente LSP puro;
|
|
2. o Studio já possui serviços de `compiler` que devem continuar sendo a fonte real de comportamento semântico.
|
|
|
|
Logo, o problema não é "inventar um cliente" nem "reescrever a semântica". O problema é definir corretamente:
|
|
|
|
1. o que é boundary interno reutilizável do Studio;
|
|
2. o que é adapter concreto de protocolo;
|
|
3. e onde termina a influência do protocolo externo.
|
|
|
|
Essa separação reduz acoplamento, melhora teste e evita que detalhes de `LSP4J` ou do transporte contaminem o restante da base.
|
|
|
|
Também existe uma prioridade explícita de rollout:
|
|
|
|
1. primeiro consolidar a arquitetura;
|
|
2. depois adicionar capacidade semântica por camadas;
|
|
3. sem obrigar a primeira implementação a já ser semanticamente rica.
|
|
|
|
Isso evita repetir o padrão anterior de crescer funcionalidade em cima de uma base estrutural errada.
|
|
|
|
## Technical Specification
|
|
|
|
### 1. Module Roles
|
|
|
|
`lsp-api` MUST ser tratado como módulo de boundary interno do Studio.
|
|
|
|
Ele SHALL:
|
|
|
|
1. expor somente contratos que façam sentido para outros consumidores internos do sistema;
|
|
2. permanecer agnóstico ao protocolo LSP concreto;
|
|
3. permanecer agnóstico a `LSP4J`;
|
|
4. permanecer agnóstico ao transporte TCP ou a qualquer detalhe de socket;
|
|
5. começar com surface mínima suficiente para o lifecycle do servidor por projeto.
|
|
|
|
`lsp-v1` MUST ser tratado como o primeiro adapter concreto do boundary acima.
|
|
|
|
Ele SHALL:
|
|
|
|
1. implementar o servidor LSP;
|
|
2. carregar os DTOs e tipos de protocolo que forem necessários para falar LSP;
|
|
3. carregar a dependência de `LSP4J`;
|
|
4. realizar a tradução entre o mundo do protocolo e os serviços internos consumidos;
|
|
5. concentrar a lógica concreta de sessão e associação `projeto -> servidor`.
|
|
|
|
### 2. LSP4J Containment
|
|
|
|
O repositório MUST tratar `LSP4J` como dependência exclusiva de `lsp-v1`.
|
|
|
|
Portanto:
|
|
|
|
1. nenhum tipo de `LSP4J` MAY aparecer em `lsp-api`;
|
|
2. nenhum tipo de `LSP4J` MAY aparecer em outros módulos do Studio;
|
|
3. nenhum contrato de `lsp-api` MAY depender semanticamente de tipos, nomes ou formas obrigadas pelo `LSP4J`;
|
|
4. qualquer vazamento de `LSP4J` para fora de `lsp-v1` SHALL ser tratado como violação arquitetural.
|
|
|
|
### 3. Compiler Ownership
|
|
|
|
`lsp-v1` MUST consumir serviços existentes de `compiler` quando precisar responder capacidades editoriais e semânticas.
|
|
|
|
Isso implica:
|
|
|
|
1. `lsp-v1` MUST NOT reconstruir uma engine semântica paralela por conveniência;
|
|
2. `lsp-v1` MUST preferir compor sobre entrypoints e serviços canônicos do `compiler`;
|
|
3. qualquer lacuna percebida no `compiler` para servir o novo backend SHALL ser tratada como evolução explícita do `compiler`, e não como autorização para duplicação semântica dentro de `lsp-v1`.
|
|
|
|
### 4. Server Lifecycle
|
|
|
|
O lifecycle do servidor MUST ser project-scoped.
|
|
|
|
Regras:
|
|
|
|
1. abrir o processo Studio MUST NOT implicitamente significar "subir um servidor LSP global";
|
|
2. abrir um projeto MAY disparar `bootServer(project)` através do boundary exposto por `lsp-api`;
|
|
3. fechar um projeto MUST disparar `shutdownServer(project)` para o servidor correspondente;
|
|
4. a implementação concreta desse bootstrap/shutdown e o vínculo entre projeto e instância do servidor MUST residir em `lsp-v1`.
|
|
|
|
### 5. Internal API Minimalism
|
|
|
|
`lsp-api` MUST nascer pequeno.
|
|
|
|
Ele SHALL:
|
|
|
|
1. expor apenas o que outro consumidor interno realmente precise enxergar;
|
|
2. evitar DTOs de protocolo sem necessidade;
|
|
3. evitar antecipar capacidades futuras sem consumidor real;
|
|
4. crescer somente quando houver pressão concreta de uso interno.
|
|
|
|
O contrato inicial mínimo aceito por esta decisão é:
|
|
|
|
1. `bootServer(project)`
|
|
2. `shutdownServer(project)`
|
|
|
|
Contratos adicionais MAY ser adicionados depois, mas não fazem parte do lock inicial desta decisão.
|
|
|
|
### 6. VS Code Transport
|
|
|
|
`tools/vscode-extension` SHALL permanecer cliente LSP puro via socket TCP nesta fase.
|
|
|
|
Isso implica:
|
|
|
|
1. a extensão atual pode continuar evoluindo nesse modelo;
|
|
2. `lsp-api` MUST permanecer agnóstico a esse transporte;
|
|
3. mudanças futuras de transporte MAY ser discutidas depois, mas não fazem parte do boundary normativo inicial.
|
|
|
|
### 7. Current Mock Status
|
|
|
|
O `lsp-v1` que existe hoje para testes de conectividade entre VS Code e Studio MUST ser tratado como mock transitório.
|
|
|
|
Ele MUST NOT:
|
|
|
|
1. servir de blueprint estrutural do novo servidor;
|
|
2. servir de contrato implícito do sistema;
|
|
3. servir de justificativa para manter responsabilidades colapsadas;
|
|
4. contaminar o padrão de código alvo do backend definitivo.
|
|
|
|
O backend definitivo SHALL priorizar:
|
|
|
|
1. separação clara de responsabilidades;
|
|
2. boundaries pequenos e explícitos;
|
|
3. código fácil de manter;
|
|
4. composição sobre serviços canônicos do `compiler`;
|
|
5. isolamento rígido do adapter de protocolo.
|
|
|
|
### 8. Implementation Wave 1
|
|
|
|
A primeira onda de implementação derivada desta decisão MUST focar em transformar o mock atual em uma estrutura sólida de trabalho.
|
|
|
|
Essa onda SHALL incluir:
|
|
|
|
1. `lsp-api` mínimo com bootstrap e shutdown por projeto;
|
|
2. `lsp-v1` organizado como adapter concreto limpo, mesmo que ainda responda um conjunto reduzido ou simplificado de capacidades;
|
|
3. boot do servidor quando o projeto abrir;
|
|
4. shutdown do servidor quando o projeto fechar;
|
|
5. isolamento explícito entre boundary interno, adapter de protocolo e consumo de `compiler`.
|
|
|
|
Essa onda MUST NOT ser bloqueada pela ausência de "carne semântica" completa.
|
|
|
|
Em outras palavras:
|
|
|
|
1. é aceitável manter um comportamento LSP inicial deliberadamente simples;
|
|
2. não é aceitável manter um padrão arquitetural improvisado só porque o comportamento ainda é simples;
|
|
3. a evolução semântica futura SHALL acontecer por camadas sobre a estrutura consolidada.
|
|
|
|
## Constraints
|
|
|
|
1. Esta decisão MUST preservar a separação entre boundary interno e adapter externo.
|
|
2. Esta decisão MUST preservar `compiler` como owner semântico do sistema.
|
|
3. Esta decisão MUST impedir vazamento de `LSP4J` para fora de `lsp-v1`.
|
|
4. Esta decisão MUST impedir que o mock atual de conectividade seja usado como padrão do produto.
|
|
5. Esta decisão MUST manter `compile/build/run/debug` fora do escopo do `lsp-api` nesta fase.
|
|
6. Qualquer plano derivado desta decisão MUST refletir explicitamente o lifecycle por projeto e a contenção de protocolo em `lsp-v1`.
|
|
7. O primeiro plano derivado desta decisão MUST priorizar a consolidação estrutural do servidor antes do enriquecimento semântico.
|
|
|
|
## Revision Log
|
|
|
|
- 2026-05-05: Initial draft from AGD-0035.
|
|
- 2026-05-05: Added explicit phase-1 rollout guidance to solidify architecture before semantic depth.
|
|
- 2026-05-05: Accepted and decomposed into PLN-0065, PLN-0066, and PLN-0067.
|