119 lines
5.0 KiB
Markdown
119 lines
5.0 KiB
Markdown
---
|
|
id: PLN-0065
|
|
ticket: studio-new-lsp-api-and-v1-boundary
|
|
title: LSP Boundary and Module Scaffolding
|
|
status: done
|
|
created: 2026-05-05
|
|
completed: 2026-05-05
|
|
tags: [studio, lsp, api, boundary, modules, architecture]
|
|
---
|
|
|
|
## Objective
|
|
|
|
Recreate `prometeu-lsp:prometeu-lsp-api` and `prometeu-lsp:prometeu-lsp-v1` with a structurally correct boundary that is ready for long-term maintenance, while intentionally keeping the initial server behavior minimal.
|
|
|
|
## Background
|
|
|
|
`DEC-0032` locks that:
|
|
|
|
- `lsp-api` is an internal Studio boundary, not a mirror of the LSP protocol;
|
|
- `lsp-v1` is the concrete LSP adapter and the only module allowed to depend on `LSP4J`;
|
|
- the current mock server shape MUST NOT be treated as the product pattern;
|
|
- wave 1 prioritizes architecture and lifecycle over semantic depth.
|
|
|
|
The repository already reserves `prometeu-lsp:*` in `settings.gradle.kts`, but the modules are currently empty shells after the cleanup.
|
|
|
|
## Scope
|
|
|
|
### Included
|
|
- Recreate Gradle/module structure for `prometeu-lsp-api` and `prometeu-lsp-v1`.
|
|
- Define the minimal internal API contract for server lifecycle by project.
|
|
- Establish package boundaries that keep protocol DTOs and `LSP4J` types out of `lsp-api`.
|
|
- Add boundary-oriented tests or build checks where feasible.
|
|
|
|
### Excluded
|
|
- Wiring the server into Studio project open/close.
|
|
- Rich semantic behavior, diagnostics, definition, symbols, or incremental analysis.
|
|
- Automation channel work for `compile/build/run/debug`.
|
|
|
|
## Non-Goals
|
|
|
|
- Full language feature implementation.
|
|
- Any attempt to preserve compatibility with the legacy removed `prometeu-lsp`.
|
|
- Transport changes in the VS Code extension.
|
|
|
|
## Execution Steps
|
|
|
|
### Step 1 - Recreate the Gradle modules with explicit dependency ownership
|
|
|
|
**What:** Reintroduce the `prometeu-lsp-api` and `prometeu-lsp-v1` modules as clean boundaries.
|
|
**How:** Restore the module directories and `build.gradle.kts` files, wire them in `settings.gradle.kts`, and keep dependencies explicit:
|
|
|
|
- `prometeu-lsp-api` depends only on stable internal modules it truly needs;
|
|
- `prometeu-lsp-v1` depends on `prometeu-lsp-api`, `compiler` services it consumes, and `LSP4J`;
|
|
- no other Studio module depends on `LSP4J`.
|
|
|
|
**File(s):** `settings.gradle.kts`, `prometeu-lsp/prometeu-lsp-api/build.gradle.kts`, `prometeu-lsp/prometeu-lsp-v1/build.gradle.kts`, affected root/module build files.
|
|
|
|
### Step 2 - Define the minimal internal lifecycle contract in `lsp-api`
|
|
|
|
**What:** Create the smallest stable API needed by the Studio host.
|
|
**How:** Add internal contracts such as a project-scoped `bootServer(project)` and `shutdownServer(project)` surface plus the minimal supporting DTO/entity types required by that lifecycle. Keep the API transport-agnostic and free of protocol DTOs.
|
|
**File(s):** `prometeu-lsp/prometeu-lsp-api/src/main/java/**`.
|
|
|
|
### Step 3 - Define the adapter shape in `lsp-v1`
|
|
|
|
**What:** Establish the internal code organization of the concrete adapter.
|
|
**How:** Create clear package slices inside `lsp-v1`, such as:
|
|
|
|
- lifecycle/bootstrap,
|
|
- server host/transport,
|
|
- protocol DTO mapping,
|
|
- compiler-facing service bridge.
|
|
|
|
The implementation may stay behaviorally dumb, but the structure MUST already reflect the final responsibility split.
|
|
**File(s):** `prometeu-lsp/prometeu-lsp-v1/src/main/java/**`.
|
|
|
|
### Step 4 - Add boundary conformance tests
|
|
|
|
**What:** Prevent architectural drift from day 1.
|
|
**How:** Add tests or static checks that fail if:
|
|
|
|
- `lsp-api` imports `LSP4J`;
|
|
- protocol DTOs leak into `lsp-api`;
|
|
- non-`lsp-v1` Studio modules start importing `LSP4J`.
|
|
|
|
**File(s):** `prometeu-lsp/prometeu-lsp-api/src/test/java/**`, `prometeu-lsp/prometeu-lsp-v1/src/test/java/**`, or build-level checks if that is cleaner.
|
|
|
|
## Test Requirements
|
|
|
|
### Unit Tests
|
|
- Verify the lifecycle contracts in `lsp-api` have deterministic defaults and null-safety.
|
|
- Verify `lsp-v1` module-local bootstrap pieces can be instantiated without a running Studio shell.
|
|
- Verify boundary checks catch `LSP4J` leakage.
|
|
|
|
### Integration Tests
|
|
- Run a root or targeted Gradle build proving the new modules compile and coexist with `prometeu-studio` and `prometeu-app`.
|
|
|
|
### Manual Verification
|
|
- Inspect the recreated module tree and confirm `lsp-api` contains no protocol or `LSP4J` types.
|
|
|
|
## Acceptance Criteria
|
|
|
|
- [x] `prometeu-lsp-api` and `prometeu-lsp-v1` exist again as active modules.
|
|
- [x] `lsp-api` exposes only internal lifecycle-oriented contracts.
|
|
- [x] `lsp-v1` is the only module allowed to depend on `LSP4J`.
|
|
- [x] The new module structure expresses clear responsibility boundaries even with dumb behavior.
|
|
- [x] Boundary conformance is covered by tests or equivalent build checks.
|
|
|
|
## Dependencies
|
|
|
|
- `DEC-0032` accepted and normatively locked.
|
|
- Current Gradle graph and module includes available for reactivation.
|
|
|
|
## Risks
|
|
|
|
- Reintroducing the modules too loosely can recreate the same ambiguity that killed the legacy stack.
|
|
- An underspecified API can force churn later; an oversized API can lock the wrong shape too early.
|
|
- Build-only enforcement may miss architectural drift unless the checks are explicit.
|