prometeu-studio/discussion/lessons/DSC-0032-studio-new-lsp-api-and-v1-boundary/LSN-0047-project-scoped-lsp-boundary-and-protocol-containment.md
2026-05-07 14:53:33 +01:00

107 lines
4.4 KiB
Markdown

---
id: LSN-0047
ticket: studio-new-lsp-api-and-v1-boundary
title: Project-Scoped LSP Boundary and Protocol Containment
created: 2026-05-07
tags: [studio, lsp, vscode, protocol, api, boundary, compiler]
---
## Context
After the legacy embedded editor stack was removed, Prometeu needed a new LSP baseline without repeating the old mistake of collapsing protocol, session lifecycle, host UI, and semantic ownership into one module.
The main architectural pressure came from two facts:
- the VS Code extension already existed as a real LSP client over TCP,
- and the compiler already existed as the canonical owner of semantic behavior.
That meant the missing piece was not "add editor features first". The missing piece was a strict boundary that let the Studio host, the protocol adapter, and the compiler evolve without contaminating each other.
## Key Decisions
### Keep `lsp-api` Minimal and Internal
**What:**
`lsp-api` became a narrow internal Studio boundary, starting with project-scoped lifecycle operations such as boot and shutdown instead of mirroring the LSP protocol.
**Why:**
The Studio needed a reusable internal service boundary, not a second copy of the external wire protocol.
**Trade-offs:**
The API starts intentionally small and may need explicit growth later, but that is safer than locking protocol-shaped DTOs into the internal architecture too early.
### Contain `LSP4J` and Protocol DTOs Inside `lsp-v1`
**What:**
`lsp-v1` became the only concrete protocol adapter and the only module allowed to depend on `LSP4J`.
**Why:**
Protocol libraries are integration details. If they leak outward, the host architecture starts depending on the current transport and implementation framework instead of on stable domain boundaries.
**Trade-offs:**
This forces explicit mapping layers and a little more ceremony, but it keeps protocol churn from infecting the rest of the codebase.
### Make the Server Lifecycle Project-Scoped
**What:**
The LSP server now belongs to project open/close lifecycle instead of global Studio process startup.
**Why:**
Project scope is the real ownership boundary for source roots, compiler context, and editor-facing behavior.
**Trade-offs:**
Lifecycle wiring is slightly more involved, but resource ownership becomes predictable and multi-project behavior stays sane.
### Keep `compiler` as Semantic Owner Even in a Dumb First Wave
**What:**
The baseline server remained intentionally simple in behavior, but its request handling already routes through compiler-facing bridge seams.
**Why:**
A "temporary mock" becomes dangerous when it also becomes the architecture. The repository needed a structurally correct baseline before adding semantic depth.
**Trade-offs:**
Wave 1 delivered less feature richness, but it created a safe foundation for later layering.
## Patterns and Algorithms
### Pattern: Internal Boundary, External Adapter
The stable split is:
1. `lsp-api` exposes internal lifecycle operations,
2. `lsp-v1` speaks protocol and transport,
3. `compiler` owns semantic and analysis behavior,
4. the VS Code extension remains an ordinary external LSP client.
### Pattern: Build the Seams Before the Features
The server can begin "dumb" in capability coverage if:
- the lifecycle boundary is already correct,
- compiler access already flows through explicit bridge services,
- and protocol containment is already enforced.
That sequence is safer than shipping richer features on top of a blurred module boundary.
## Pitfalls
- Do not let `lsp-api` grow into a shadow copy of the LSP protocol.
- Do not import `LSP4J` outside `lsp-v1`, even for convenience.
- Do not move semantic ownership into the protocol adapter just because the adapter is the caller-facing layer.
- Do not boot a global server for the entire Studio process when the actual ownership boundary is the project session.
- Do not treat a connectivity mock as an acceptable long-term module shape.
## References
- `DEC-0032` Boundary normativo entre lsp-api, lsp-v1 e a extensao VS Code
- `PLN-0065` LSP Boundary and Module Scaffolding
- `PLN-0066` Project-Scoped LSP Server Lifecycle in Studio
- `PLN-0067` Compiler-Backed Dumb LSP Server Baseline
## Takeaways
- Protocol adapters should stay narrow and concrete; internal Studio boundaries should stay protocol-agnostic.
- Project-scoped lifecycle is the correct owner for the LSP server.
- A dumb first wave is acceptable only when the architecture is already correct.