prometeu-studio/docs/specs/compiler/23. Compiler Pipeline Entry Points Specification.md
bQUARKz e456bb8d7a
implements PLN-0137 (6/7) module-ref-completion
Completion inside a ModuleRef lists project and stdlib modules the
current resolver can already name. Completion after a dot stays the
existing member list. Items remain eager, resolveProvider stays false,
and there is no snippet or ranking score.
2026-09-22 09:13:40 +01:00

365 lines
23 KiB
Markdown

# Compiler Pipeline Entry Points Specification
Status: Draft v1 (Operational Entry-Point Baseline)
Applies to: canonical compiler entrypoints, stage-terminal boundaries, and result contracts for `analyze`, `compile`, and `build`
## 1. Purpose
This document defines the canonical operational entrypoints of the shared compiler pipeline.
Its purpose is to make the compiler usable through explicit entrypoints instead of one monolithic public build invocation, while preserving one shared semantic pipeline for all supported frontends.
## 2. Scope
This document defines:
- the canonical stage order shared by compiler entrypoints,
- the frontend provider and registry boundary used by shared compiler composition,
- the terminal stage and mandatory behavior of `analyze`,
- the terminal stage and mandatory behavior of `compile`,
- the terminal stage and mandatory behavior of `build`,
- the minimum public result contracts for those entrypoints,
- and the context/config constraints that allow different callers without creating parallel pipeline semantics.
This document does not define:
- one mandatory Java class or package layout,
- editor-specific source providers or document-session providers,
- frontend-specific semantic facts beyond the minimum shared `AnalysisSnapshot` contract,
- dynamic frontend plugin discovery,
- or one mandatory CLI architecture.
## 3. Authority and Precedence
Normative precedence:
1. Runtime authority (`docs/specs/hardware/topics/chapter-2.md`, `chapter-3.md`, `chapter-9.md`, `chapter-12.md`, `chapter-16.md`)
2. Bytecode authority (`docs/specs/bytecode/ISA_CORE.md`)
3. `14. Name Resolution and Module Linking Specification.md`
4. `20. IRBackend to IRVM Lowering Specification.md`
5. `21. IRVM Optimization Pipeline Specification.md`
6. `15. Bytecode and PBX Mapping Specification.md`
7. `19. Verification and Safety Checks Specification.md`
8. This document
If a rule here conflicts with a higher-precedence authority, it is invalid.
## 4. Normative Inputs
This document depends on:
- `14. Name Resolution and Module Linking Specification.md`
- `15. Bytecode and PBX Mapping Specification.md`
- `19. Verification and Safety Checks Specification.md`
- `20. IRBackend to IRVM Lowering Specification.md`
- `21. IRVM Optimization Pipeline Specification.md`
- `docs/specs/compiler-languages/pbs/13. Lowering IRBackend Specification.md`
- the frontend-owned semantic presentation contract published through `FrontendSpec`
## 5. Canonical Shared Pipeline
The compiler MUST expose one canonical shared pipeline.
The canonical stage order is:
1. `ResolveDepsPipelineStage`
2. `LoadSourcesPipelineStage`
3. `FrontendPhasePipelineStage`
4. `AssembleLifecyclePipelineStage`
5. `LowerToIRVMPipelineStage`
6. `OptimizeIRVMPipelineStage`
7. `EmitBytecodePipelineStage`
8. `LinkBytecodePipelineStage`
9. `VerifyBytecodePipelineStage`
10. `WriteBytecodeArtifactPipelineStage`
Public entrypoints MAY terminate early according to this document, but they MUST NOT:
1. reorder these stages,
2. redefine their shared semantic meaning,
3. or create parallel compiler pipelines under the same public entrypoint names.
## 6. Entry Point Contracts
### 6.1 `analyze`
`analyze` MUST terminate at `AssembleLifecyclePipelineStage`.
`analyze` is defined as:
1. `ResolveDeps`
2. `LoadSources`
3. `FrontendPhase`
4. `AssembleLifecycle`
`analyze` MUST:
1. resolve workspace/dependency inputs needed by the frontend,
2. load source surfaces admitted by the selected compiler configuration,
3. run frontend semantic analysis and emit a declarative `IRBackend`,
4. assemble the common lifecycle from `IRLifecycleDeclaration` when present,
5. return an `AnalysisSnapshot` or equivalent result contract whose `IRBackend` is fully assembled when the handoff is executable,
6. and remain free of backend artifact side effects.
`analyze` MUST NOT:
1. lower to IRVM,
2. optimize IRVM,
3. emit bytecode,
4. run bytecode link/verify gates,
5. or persist artifact files.
### 6.2 `compile`
`compile` MUST terminate at `VerifyBytecodePipelineStage`.
`compile` is defined as:
1. `analyze`
2. `LowerToIRVM`
3. `OptimizeIRVM`
4. `EmitBytecode`
5. `LinkBytecode`
6. `VerifyBytecode`
`compile` MUST:
1. preserve the canonical executable path used to produce an in-memory executable artifact,
2. produce a validated executable result in memory,
3. include bytecode emission, bytecode link precheck, and bytecode verification,
4. and preserve the correctness expectations of the current executable path used by PBS.
`compile` MUST NOT persist artifact files.
### 6.3 `build`
`build` MUST terminate at `WriteBytecodeArtifactPipelineStage`.
`build` is defined as:
1. `compile`
2. `WriteBytecodeArtifact`
`build` MUST:
1. preserve the current default filesystem-oriented artifact behavior,
2. write the executable artifact only after the `compile` contract has been satisfied,
3. and remain the canonical artifact-materialization entrypoint for filesystem-backed callers.
## 7. Result Contracts
### 7.1 `AnalysisSnapshot`
`AnalysisSnapshot` is the minimum shared result contract for `analyze`.
`AnalysisSnapshot` MUST expose at minimum:
1. diagnostics,
2. semantic facts produced by the frontend,
3. stable references to loaded sources, including the equivalent of `FileTable`,
4. and workspace-resolution metadata required by tooling consumers.
Implementations MAY add fields, but they MUST NOT omit those minimum elements.
### 7.2 Compile result
The `compile` result MUST expose at minimum:
1. the validated in-memory executable artifact,
2. the equivalent of `bytecodeModule`,
3. the equivalent of serialized bytecode bytes,
4. and enough metadata to allow `build` to persist the artifact without recompiling through another semantic path.
### 7.3 Build result
The `build` result MUST expose at minimum:
1. the persisted artifact location,
2. the compile payload from which the artifact was produced or an equivalent stable bridge to it,
3. and the outcome needed by filesystem-backed callers to confirm successful artifact materialization.
## 8. Context and Configuration Model
The compiler MAY accept distinct config/context inputs per entrypoint in order to support CLI, editor, LSP, and other callers.
Those configs/contexts MAY vary:
1. source acquisition strategies,
2. sinks or collectors,
3. composition helpers,
4. and the exact shape of public result wrappers.
Those configs/contexts MUST NOT:
1. change the canonical stage order for a given entrypoint,
2. redefine stage semantics,
3. or create an alternate semantic pipeline under the public names `analyze`, `compile`, or `build`.
Filesystem-default composition MUST happen outside the pipeline core.
## 8.1 FrontendSpec-Owned Semantic Presentation Contract
`FrontendSpec` MUST remain the canonical static contract surface for frontend-owned semantic presentation metadata.
At minimum, that contract MUST allow frontend publication of:
1. stable frontend-owned `semanticKeys`,
2. frontend-owned `resources`,
3. and enough static metadata for downstream semantic consumers to derive a consumable descriptor without inventing host-owned fallback semantics.
This contract MUST NOT:
1. move frontend semantic presentation ownership into Studio,
2. move frontend semantic presentation ownership into LSP,
3. or force frontend semantic output into a shared artificial host vocabulary.
Tooling consumers such as integrated LSP and Studio MAY derive downstream descriptors from `FrontendSpec`, but they MUST treat `FrontendSpec` as the canonical source rather than a host-owned replacement contract.
## 8.2 Frontend-Owned Inline Hint Contract Authority
Frontend-owned inline hint semantics MUST remain frontend-authored even when transported through tooling consumers.
When downstream semantic consumers require static contract metadata for inline hints, that metadata MUST come from `FrontendSpec` or from another accepted frontend-owned contract surface explicitly introduced for that purpose.
At minimum, any accepted frontend-owned inline hint contract authority MUST preserve:
1. frontend ownership of hint existence policy,
2. frontend ownership of hint semantic meaning,
3. enough contract metadata for `prometeu-lsp` to transport hint payloads without inventing host-owned semantics,
4. and enough contract clarity for Studio to render hints mechanically rather than semantically reinterpret them.
This authority model MUST NOT:
1. move semantic inline hint ownership into Studio,
2. move semantic inline hint policy into LSP,
3. or imply that the host editor may synthesize semantic hints when the frontend did not publish them.
## 8.3 Frontend Provider and Registry Contract
The shared compiler composition surface MUST represent each registered frontend through a `FrontendProvider` or equivalent provider contract.
At minimum, each provider MUST expose:
1. `specification()`, returning the frontend-owned static contract, including its stable `languageId`;
2. `compiler()`, returning the compiler-facing frontend service used by the shared build pipeline;
3. `languageService()`, returning an optional editor-facing language-service capability for tooling consumers.
`compiler()` is the only required executable frontend capability. It MUST be sufficient for `analyze`, `compile`, `build`, and backend-facing pipeline flows.
`languageService()` MUST be optional. A frontend that supports compilation but does not provide editor services MUST remain a valid provider. Absence of `languageService()` MUST NOT prevent project analysis, compilation, backend lowering, bytecode emission, verification, or artifact writing.
The first shared editor-facing contract SHOULD remain an aggregated language-service capability surface. The common compiler contract MUST NOT require separate top-level service interfaces for each editor feature until a future accepted decision and plan identify a real lifecycle, ownership, or testing boundary that requires that split.
When exposed, editor-facing capabilities MAY include:
1. diagnostics intended for live editor sessions,
2. completion,
3. hover,
4. definition and navigation,
5. signature help,
6. semantic tokens for a live document,
7. formatting,
8. rename,
9. code actions,
10. and other host-facing editor assistance.
These capabilities are optional unless a future frontend- or host-specific decision makes one of them mandatory for a narrower surface. Tooling consumers MUST query capability availability before invoking editor-specific behavior.
Absent editor capabilities MUST have deterministic fallback behavior at tooling boundaries:
1. collection-shaped responses SHOULD be empty;
2. scalar optional responses SHOULD be absent or use a documented neutral response;
3. host protocols that can represent unsupported operations SHOULD do so explicitly;
4. and absent editor capability MUST NOT be reported as a compiler failure.
When a frontend exposes definition or navigation, each returned location MUST identify a compiler-known physical source file. A resolved symbol without a physical file MUST produce an empty definition response. Tooling MUST NOT require virtual documents, untitled buffers, or synthetic URIs for this capability.
When a frontend exposes find-references, each returned usage or declaration location MUST identify a compiler-known physical source file. A cursor offset whose definition response is empty MUST produce an empty references response. Host `includeDeclaration` MAY add the canonical declaration location only when that declaration is a compiler-known physical source file; it MUST NOT invent a virtual, untitled, or synthetic location.
When a frontend exposes document symbols or outline, the result MUST be the named declaration tree of the requested document. Presence, hierarchy, and ranges MUST come from that document's recovered syntax tree. Semantic success MUST NOT be required. Semantic enrichment MUST NOT drop a named declaration that the syntax tree still exposes. A missing syntax tree MUST produce an empty list. Document symbols MUST NOT be a workspace symbol index, folding ranges, or a navigation list of foreign files.
When a frontend exposes workspace symbols, the result MUST be a flat search of named declarations whose locations identify compiler-known physical source files of the current analysis. Presence, names, kinds, details, and ranges MUST come from the recovered syntax of those files. Semantic success MUST NOT be required. Semantic enrichment MUST NOT drop a named declaration that the syntax tree still exposes. A missing analysis surface MUST produce an empty list. The workspace-symbol request MUST NOT require an open text document. A declaration without a compiler-known physical file MUST be omitted. Tooling MUST NOT require virtual documents, untitled buffers, or synthetic URIs for this capability. Workspace symbols MUST NOT be a document outline, folding ranges, a persistent symbol index, or a navigation list of virtual locations.
When a frontend exposes rename, the result MUST be a validated workspace edit of identifier spans whose locations identify compiler-known physical source files. Identity MUST be the physical declaration locations that definition returns at the cursor. A local or parameter name span MUST still be renameable when definition at that offset is empty. Each rewritten location MUST identify a compiler-known physical source file. A cursor that is not renameable, including builtins, virtual paths, unresolved names, keywords, comments, strings, import aliases and uses of those aliases, error case labels without their own span, and barrel files, MUST produce a protocol error or a null prepareRename result. Tooling MUST NOT return a successful empty workspace edit for a refused cursor or an invalid new name. The new name MUST be a language identifier that is not a keyword and MUST NOT collide in the same binding space, ignoring the sites being rewritten and the overload set being renamed. The server MUST NOT write files and MUST NOT rename file paths. Host prepareRename MUST advertise a prepareProvider when rename is exposed. Tooling MUST NOT require virtual documents, untitled buffers, or synthetic URIs for this capability.
When a frontend exposes code actions, the result MUST be quick fixes only: one workspace edit tied to a diagnostic of the requested physical document. The frontend MUST produce each repair from that document's syntax. Each repair MUST name the stable diagnostic code, the primary span, and exactly one local text edit. Tooling MUST transport that repair. Tooling MUST NOT choose the edit by parsing the diagnostic message or by a diagnostic-code table. A repair MUST NOT be a required field of compiler diagnostics and MUST NOT be published inside diagnostic data. The published diagnostic MUST carry the stable code so a later code-action request can match it. A repair MUST be returned only when the request context contains a diagnostic with the same code and the same primary range. An empty diagnostic context MUST produce an empty list. The edit MUST change only the requested physical source file. The server MUST NOT write files, MUST NOT return a command, and MUST NOT require a resolve round trip. A missing code-action capability MUST NOT advertise code actions and MUST produce an empty list rather than a protocol error. Virtual, untitled, or synthetic documents MUST NOT receive an edit. Code actions MUST NOT include organize-imports, source actions, refactors, or generated stubs unless a future accepted decision says so.
Compiler diagnostics and editor diagnostics are distinct ownership surfaces. Diagnostics returned by `analyze`, `compile`, and `build` are compiler contract output. Editor diagnostics MAY reuse compiler analysis results, live overlays, caches, or cancellation-aware tooling state, but a frontend MUST NOT be required to provide editor diagnostics in order to compile.
When tooling publishes an editor diagnostic, `source` MUST be the `languageId` of the bound frontend project. `code` MUST be the stable compiler diagnostic code when one exists, and MUST be empty when the compiler diagnostic has none. Tooling MUST NOT copy that code into `source`. Tooling MUST NOT publish related locations, compiler phase, or a repair payload on the editor diagnostic.
When a frontend exposes document links, each link MUST cover the span of a module reference whose resolved destination is a compiler-known regular file. A module reference that does not resolve to a regular file MUST produce no link. Tooling MUST NOT target virtual, untitled, or synthetic URIs, including virtual stdlib documents. Document links MUST NOT replace definition. A missing document-link capability MUST NOT be advertised and MUST produce an empty list rather than a protocol error.
When a frontend exposes folding ranges, the ranges MUST come from recovered syntax spans for top-level `fn`, `struct`, `service`, `contract`, `enum`, `error`, `callback`, and `host` declarations, their bodies, and `Doc` text blocks. A parameter list MUST fold from the parenthesis pair. A brace, parenthesis, or text-block delimiter that the recovered tree does not cover MUST still produce a token range, including an unmatched opener through the end of the text. Folding ranges MUST NOT be document symbols.
When a frontend exposes selection ranges, the chain at a cursor MUST run from the inside outward in this order: identifier, argument or parameter list, block or `Doc` text block, declaration. A layer that does not contain the cursor MUST be omitted. A missing folding or selection capability MUST NOT be advertised and MUST produce an empty list rather than a protocol error.
When a frontend exposes completion inside a module reference, the candidates MUST be project and stdlib modules the current module resolver can already name. Completion outside a module reference MUST keep its existing member and general candidates. Completion items MUST stay eager. `resolveProvider` MUST stay false. Snippets and a new ranking score MUST NOT be added.
When a frontend exposes semantic tokens, the lexical token provider remains the baseline. An identifier token MAY be replaced with an existing semantic key when the same resolution used by hover names that symbol and an existing key matches it. Resolution failure, a broken file, or a symbol with no existing key MUST keep the baseline token. This overlay MUST NOT add a semantic-token key.
When a frontend exposes formatting, it MUST be full-document formatting only. Range formatting and on-type formatting MUST NOT be advertised. The formatter MUST reprint the existing token stream. It MUST NOT reorder declarations, join lines, or split lines. Indentation MUST be four spaces and MUST change only where brace or parenthesis nesting changes. The interior of a `Doc` text block MUST be copied unchanged. A comment MUST stay on the line of the token it already follows. A missing formatting capability MUST NOT be advertised and MUST produce an empty edit list rather than a protocol error.
`FrontendSpec` remains the source of static frontend-owned presentation metadata such as semantic vocabularies, host projections, and visual themes. Producing semantic tokens for a live document is an optional editor-facing capability; the existence of static presentation metadata MUST NOT imply that every frontend can provide live semantic-token results.
The frontend registry MUST resolve providers by `languageId`. A lookup for an unknown `languageId` MUST fail explicitly with a diagnostic-friendly error. Unknown languages MUST NOT silently fall back to PBS or to any other frontend.
Common compiler, build pipeline, and Studio-facing consumers MUST obtain frontend behavior through provider lookup. They MUST NOT directly instantiate frontend-specific compiler services, except inside the frontend provider itself or inside an approved application composition root.
Provider registration MUST be explicit in v1. The registry contract MUST NOT use dynamic plugin discovery, reflection-based discovery, classpath scanning, external JAR loading, or runtime plugin installation to discover frontends.
PBS is the only initial real provider for this contract. PBS MAY be registered by an application composition root, but PBS MUST NOT become an exclusive semantic owner of the shared compiler pipeline.
A compile-only `FrontendProvider` registered by `languageId` MUST be a valid participant of `analyze`, `compile`, and `build`. The shared pipeline MUST NOT require PBS frontend types, `.pbs` or `.barrel` sources, or PBS stdlib in order to emit verified bytecode. Test-only frontends MAY exist solely as fixtures. They MUST NOT be product languages, MUST NOT be registered by default bootstrap or Studio composition, and MUST NOT be discovered by plugin scanning, classpath scanning, or external JAR loading.
The frontend registry MUST expose explicit `register` and `unregister` operations. `unregister` MUST refuse to remove the default PBS provider. Lookup of an unknown `languageId` MUST fail explicitly. `unregister` of an unknown `languageId` MUST be a no-op.
## 9. Public Surface Rule
The shared compiler public surface MUST expose explicit entrypoints equivalent in meaning to:
1. `analyze(config, logs)`
2. `compile(config, logs)`
3. `build(config, logs)`
The exact method or service names MAY vary, but the semantic split MUST remain explicit.
The legacy public concept `run` MUST NOT remain the normative public entrypoint.
The behavior previously associated with default `run` MUST be expressed as `build` with filesystem-oriented config/context assembled outside the pipeline itself.
## 10. Compatibility Rule
This document MUST preserve compatibility with the current executable path that produces artifacts for PBS.
At minimum, that compatibility covers:
1. the same semantic stage ordering up to executable artifact production,
2. the same correctness envelope for the in-memory executable artifact before persistence,
3. and no regression in emit/link/verify safety behavior.
PBS is a baseline correctness consumer for this path, but PBS MUST NOT become an exclusive semantic owner of the public compiler entrypoint surface.
## 11. Explicit Deferrals
The following remain deferred:
- editor-specific source-provider contracts,
- richer multi-profile result types beyond the minimum contracts in this document,
- and frontend-specific analysis payload extensions beyond the required shared `AnalysisSnapshot` minimum.
## 12. Non-Goals
- Creating separate public pipelines per frontend.
- Replacing backend, bytecode, or runtime authority documents.
- Freezing one internal implementation architecture prematurely.
## 13. Exit Criteria
This document is healthy when:
1. the compiler entrypoints are explicit and stable,
2. the terminal stage for each entrypoint is unambiguous,
3. the minimum result contracts are explicit,
4. `run` no longer acts as a normative public concept,
5. and caller-specific contexts are constrained without opening semantic drift.