diff --git a/discussion/.backups/index.ndjson.20260330-194358.bak b/discussion/.backups/index.ndjson.20260330-194358.bak new file mode 100644 index 00000000..e8364a4d --- /dev/null +++ b/discussion/.backups/index.ndjson.20260330-194358.bak @@ -0,0 +1,12 @@ +{"type":"meta","next_id":{"DSC":12,"AGD":12,"DEC":8,"PLN":12,"LSN":25,"CLSN":1}} +{"type":"discussion","id":"DSC-0001","status":"done","ticket":"studio-docs-import","title":"Import docs/studio into discussion-framework artifacts","created_at":"2026-03-26","updated_at":"2026-03-26","tags":["studio","migration","discussion-framework","docs-import"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0001","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0001-assets-workspace-execution-wave-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0002","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0002-bank-composition-editor-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0003","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0003-mental-model-asset-mutations-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0004","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0004-mental-model-assets-workspace-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0005","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0005-mental-model-studio-events-and-components-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0006","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0006-mental-model-studio-shell-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0007","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0007-pack-wizard-shell-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0008","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0008-project-scoped-state-and-activity-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0016","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0016-studio-docs-import-pattern.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"}]} +{"type":"discussion","id":"DSC-0002","status":"open","ticket":"palette-management-in-studio","title":"Palette Management in Studio","created_at":"2026-03-26","updated_at":"2026-03-26","tags":["studio","legacy-import","palette-management","tile-bank","packer-boundary"],"agendas":[{"id":"AGD-0002","file":"AGD-0002-palette-management-in-studio.md","status":"open","created_at":"2026-03-26","updated_at":"2026-03-26"}],"decisions":[],"plans":[],"lessons":[]} +{"type":"discussion","id":"DSC-0003","status":"done","ticket":"packer-docs-import","title":"Import docs/packer into discussion-framework artifacts","created_at":"2026-03-26","updated_at":"2026-03-26","tags":["packer","migration","discussion-framework","docs-import"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0009","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0009-mental-model-packer-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0010","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0010-asset-identity-and-runtime-contract-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0011","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0011-foundations-workspace-runtime-and-build-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0012","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0012-runtime-ownership-and-studio-boundary-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0013","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0013-metadata-convergence-and-runtime-sink-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0014","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0014-pack-wizard-summary-validation-and-pack-execution-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0015","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0015-tile-bank-packing-contract-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0017","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0017-packer-docs-import-pattern.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"}]} +{"type":"discussion","id":"DSC-0004","status":"open","ticket":"tilemap-and-metatile-runtime-binary-layout","title":"Tilemap and Metatile Runtime Binary Layout","created_at":"2026-03-26","updated_at":"2026-03-26","tags":["packer","legacy-import","tilemap","metatile","runtime-layout"],"agendas":[{"id":"AGD-0004","file":"AGD-0004-tilemap-and-metatile-runtime-binary-layout.md","status":"open","created_at":"2026-03-26","updated_at":"2026-03-26"}],"decisions":[],"plans":[],"lessons":[]} +{"type":"discussion","id":"DSC-0005","status":"open","ticket":"variable-tile-bank-palette-serialization","title":"Variable Tile Bank Palette Serialization","created_at":"2026-03-26","updated_at":"2026-03-26","tags":["packer","legacy-import","tile-bank","palette-serialization","versioning"],"agendas":[{"id":"AGD-0005","file":"AGD-0005-variable-tile-bank-palette-serialization.md","status":"open","created_at":"2026-03-26","updated_at":"2026-03-26"}],"decisions":[],"plans":[],"lessons":[]} +{"type":"discussion","id":"DSC-0006","status":"done","ticket":"pbs-game-facing-asset-refs-and-call-result-discard","title":"PBS Game-Facing Asset References and Ignored Call Result Lowering","created_at":"2026-03-27","updated_at":"2026-03-30","tags":["compiler","pbs","ergonomics","lowering","runtime","asset-identity","expression-statements"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0024","file":"discussion/lessons/DSC-0006-pbs-game-facing-asset-refs-and-call-result-discard/LSN-0024-addressable-surface-host-metadata-and-ignored-value-discipline.md","status":"done","created_at":"2026-03-30","updated_at":"2026-03-30"}]} +{"type":"discussion","id":"DSC-0007","status":"done","ticket":"pbs-learn-to-discussion-lessons-migration","title":"Migrate PBS Learn Documents into Discussion Lessons","created_at":"2026-03-27","updated_at":"2026-03-27","tags":["compiler","pbs","migration","discussion-framework","lessons","learn-prune"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0018","file":"discussion/lessons/DSC-0007-pbs-learn-to-discussion-lessons-migration/LSN-0018-pbs-ast-and-parser-contract-legacy.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0019","file":"discussion/lessons/DSC-0007-pbs-learn-to-discussion-lessons-migration/LSN-0019-pbs-name-resolution-and-linking-legacy.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0020","file":"discussion/lessons/DSC-0007-pbs-learn-to-discussion-lessons-migration/LSN-0020-pbs-runtime-values-identity-memory-boundaries-legacy.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0021","file":"discussion/lessons/DSC-0007-pbs-learn-to-discussion-lessons-migration/LSN-0021-pbs-diagnostics-and-conformance-governance-legacy.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0022","file":"discussion/lessons/DSC-0007-pbs-learn-to-discussion-lessons-migration/LSN-0022-pbs-globals-lifecycle-and-published-entrypoint-legacy.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"}]} +{"type":"discussion","id":"DSC-0008","status":"done","ticket":"pbs-low-level-asset-manager-surface","title":"PBS Low-Level Asset Manager Surface for Runtime AssetManager","created_at":"2026-03-27","updated_at":"2026-03-27","tags":["compiler","pbs","runtime","asset-manager","host-abi","stdlib","asset"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0023","file":"discussion/lessons/DSC-0008-pbs-low-level-asset-manager-surface/LSN-0023-lowassets-runtime-aligned-sdk-surface.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"}]} +{"type":"discussion","id":"DSC-0009","status":"open","ticket":"studio-debugger-workspace-integration","title":"Integrate ../debugger into Studio as a dedicated workspace","created_at":"2026-03-30","updated_at":"2026-03-30","tags":["studio","debugger","workspace","integration","shell"],"agendas":[{"id":"AGD-0009","file":"AGD-0009-studio-debugger-workspace-integration.md","status":"open","created_at":"2026-03-30","updated_at":"2026-03-30"}],"decisions":[],"plans":[],"lessons":[]} +{"type":"discussion","id":"DSC-0010","status":"open","ticket":"studio-code-editor-workspace-foundations","title":"Establish Code Editor workspace foundations in Studio without LSP","created_at":"2026-03-30","updated_at":"2026-03-30","tags":["studio","editor","workspace","multi-frontend","lsp-deferred"],"agendas":[{"id":"AGD-0010","file":"AGD-0010-studio-code-editor-workspace-foundations.md","status":"open","created_at":"2026-03-30","updated_at":"2026-03-30"}],"decisions":[],"plans":[],"lessons":[]} +{"type":"discussion","id":"DSC-0011","status":"open","ticket":"compiler-analyze-compile-build-pipeline-split","title":"Split compiler pipeline into analyze, compile, and build entrypoints","created_at":"2026-03-30","updated_at":"2026-03-30","tags":["compiler","pipeline","artifacts","build","analysis"],"agendas":[{"id":"AGD-0011","file":"AGD-0011-compiler-analyze-compile-build-pipeline-split.md","status":"accepted","created_at":"2026-03-30","updated_at":"2026-03-30"}],"decisions":[{"id":"DEC-0007","file":"DEC-0007-compiler-analyze-compile-build-pipeline-split.md","status":"in_progress","created_at":"2026-03-30","updated_at":"2026-03-30","ref_agenda":"AGD-0011"}],"plans":[{"id":"PLN-0009","file":"PLN-0009-compiler-pipeline-spec-and-contract-propagation.md","status":"done","created_at":"2026-03-30","updated_at":"2026-03-30","ref_decisions":["DEC-0007"]},{"id":"PLN-0010","file":"PLN-0010-refactor-builder-pipeline-service-into-entrypoints.md","status":"done","created_at":"2026-03-30","updated_at":"2026-03-30","ref_decisions":["DEC-0007"]},{"id":"PLN-0011","file":"PLN-0011-migrate-callsites-and-tests-to-build-compile-analyze.md","status":"done","created_at":"2026-03-30","updated_at":"2026-03-30","ref_decisions":["DEC-0007"]}],"lessons":[]} diff --git a/discussion/index.ndjson b/discussion/index.ndjson index e8364a4d..b81ff8f0 100644 --- a/discussion/index.ndjson +++ b/discussion/index.ndjson @@ -1,4 +1,4 @@ -{"type":"meta","next_id":{"DSC":12,"AGD":12,"DEC":8,"PLN":12,"LSN":25,"CLSN":1}} +{"type":"meta","next_id":{"DSC":12,"AGD":12,"DEC":8,"PLN":12,"LSN":26,"CLSN":1}} {"type":"discussion","id":"DSC-0001","status":"done","ticket":"studio-docs-import","title":"Import docs/studio into discussion-framework artifacts","created_at":"2026-03-26","updated_at":"2026-03-26","tags":["studio","migration","discussion-framework","docs-import"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0001","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0001-assets-workspace-execution-wave-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0002","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0002-bank-composition-editor-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0003","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0003-mental-model-asset-mutations-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0004","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0004-mental-model-assets-workspace-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0005","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0005-mental-model-studio-events-and-components-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0006","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0006-mental-model-studio-shell-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0007","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0007-pack-wizard-shell-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0008","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0008-project-scoped-state-and-activity-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0016","file":"discussion/lessons/DSC-0001-studio-docs-import/LSN-0016-studio-docs-import-pattern.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"}]} {"type":"discussion","id":"DSC-0002","status":"open","ticket":"palette-management-in-studio","title":"Palette Management in Studio","created_at":"2026-03-26","updated_at":"2026-03-26","tags":["studio","legacy-import","palette-management","tile-bank","packer-boundary"],"agendas":[{"id":"AGD-0002","file":"AGD-0002-palette-management-in-studio.md","status":"open","created_at":"2026-03-26","updated_at":"2026-03-26"}],"decisions":[],"plans":[],"lessons":[]} {"type":"discussion","id":"DSC-0003","status":"done","ticket":"packer-docs-import","title":"Import docs/packer into discussion-framework artifacts","created_at":"2026-03-26","updated_at":"2026-03-26","tags":["packer","migration","discussion-framework","docs-import"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0009","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0009-mental-model-packer-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0010","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0010-asset-identity-and-runtime-contract-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0011","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0011-foundations-workspace-runtime-and-build-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0012","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0012-runtime-ownership-and-studio-boundary-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0013","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0013-metadata-convergence-and-runtime-sink-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0014","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0014-pack-wizard-summary-validation-and-pack-execution-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0015","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0015-tile-bank-packing-contract-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0017","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0017-packer-docs-import-pattern.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"}]} @@ -9,4 +9,4 @@ {"type":"discussion","id":"DSC-0008","status":"done","ticket":"pbs-low-level-asset-manager-surface","title":"PBS Low-Level Asset Manager Surface for Runtime AssetManager","created_at":"2026-03-27","updated_at":"2026-03-27","tags":["compiler","pbs","runtime","asset-manager","host-abi","stdlib","asset"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0023","file":"discussion/lessons/DSC-0008-pbs-low-level-asset-manager-surface/LSN-0023-lowassets-runtime-aligned-sdk-surface.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"}]} {"type":"discussion","id":"DSC-0009","status":"open","ticket":"studio-debugger-workspace-integration","title":"Integrate ../debugger into Studio as a dedicated workspace","created_at":"2026-03-30","updated_at":"2026-03-30","tags":["studio","debugger","workspace","integration","shell"],"agendas":[{"id":"AGD-0009","file":"AGD-0009-studio-debugger-workspace-integration.md","status":"open","created_at":"2026-03-30","updated_at":"2026-03-30"}],"decisions":[],"plans":[],"lessons":[]} {"type":"discussion","id":"DSC-0010","status":"open","ticket":"studio-code-editor-workspace-foundations","title":"Establish Code Editor workspace foundations in Studio without LSP","created_at":"2026-03-30","updated_at":"2026-03-30","tags":["studio","editor","workspace","multi-frontend","lsp-deferred"],"agendas":[{"id":"AGD-0010","file":"AGD-0010-studio-code-editor-workspace-foundations.md","status":"open","created_at":"2026-03-30","updated_at":"2026-03-30"}],"decisions":[],"plans":[],"lessons":[]} -{"type":"discussion","id":"DSC-0011","status":"open","ticket":"compiler-analyze-compile-build-pipeline-split","title":"Split compiler pipeline into analyze, compile, and build entrypoints","created_at":"2026-03-30","updated_at":"2026-03-30","tags":["compiler","pipeline","artifacts","build","analysis"],"agendas":[{"id":"AGD-0011","file":"AGD-0011-compiler-analyze-compile-build-pipeline-split.md","status":"accepted","created_at":"2026-03-30","updated_at":"2026-03-30"}],"decisions":[{"id":"DEC-0007","file":"DEC-0007-compiler-analyze-compile-build-pipeline-split.md","status":"in_progress","created_at":"2026-03-30","updated_at":"2026-03-30","ref_agenda":"AGD-0011"}],"plans":[{"id":"PLN-0009","file":"PLN-0009-compiler-pipeline-spec-and-contract-propagation.md","status":"done","created_at":"2026-03-30","updated_at":"2026-03-30","ref_decisions":["DEC-0007"]},{"id":"PLN-0010","file":"PLN-0010-refactor-builder-pipeline-service-into-entrypoints.md","status":"done","created_at":"2026-03-30","updated_at":"2026-03-30","ref_decisions":["DEC-0007"]},{"id":"PLN-0011","file":"PLN-0011-migrate-callsites-and-tests-to-build-compile-analyze.md","status":"done","created_at":"2026-03-30","updated_at":"2026-03-30","ref_decisions":["DEC-0007"]}],"lessons":[]} +{"type":"discussion","id":"DSC-0011","status":"done","ticket":"compiler-analyze-compile-build-pipeline-split","title":"Split compiler pipeline into analyze, compile, and build entrypoints","created_at":"2026-03-30","updated_at":"2026-03-30","tags":["compiler","pipeline","artifacts","build","analysis"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0025","file":"discussion/lessons/DSC-0011-compiler-analyze-compile-build-pipeline-split/LSN-0025-compiler-pipeline-entrypoints-and-result-boundaries.md","status":"done","created_at":"2026-03-30","updated_at":"2026-03-30"}]} diff --git a/discussion/lessons/DSC-0011-compiler-analyze-compile-build-pipeline-split/LSN-0025-compiler-pipeline-entrypoints-and-result-boundaries.md b/discussion/lessons/DSC-0011-compiler-analyze-compile-build-pipeline-split/LSN-0025-compiler-pipeline-entrypoints-and-result-boundaries.md new file mode 100644 index 00000000..c01e0208 --- /dev/null +++ b/discussion/lessons/DSC-0011-compiler-analyze-compile-build-pipeline-split/LSN-0025-compiler-pipeline-entrypoints-and-result-boundaries.md @@ -0,0 +1,110 @@ +--- +id: LSN-0025 +ticket: compiler-analyze-compile-build-pipeline-split +title: Compiler Pipeline Entrypoints and Result Boundaries +created: 2026-03-30 +tags: [compiler, pipeline, analyze, compile, build, contracts, conformance] +--- + +## Context + +The compiler pipeline used to expose one public `run` flow that always resolved dependencies, loaded sources, ran the frontend, lowered to IRVM, optimized, emitted bytecode, verified it, and finally wrote `build/program.pbx`. + +That shape hid three different intents behind one operation: + +- tooling-only semantic analysis with no artifact side effects, +- in-memory executable compilation with no disk write, +- and filesystem-backed artifact materialization. + +This became a real boundary problem once Studio and future LSP-like consumers needed semantic results without forcing PBX persistence. + +## Key Decisions + +### Keep One Canonical Pipeline, Not Three Divergent Pipelines + +**What:** +The compiler now keeps one canonical shared stage order and exposes three public entrypoints over that same pipeline: `analyze`, `compile`, and `build`. + +**Why:** +The important architectural rule is shared semantics with different terminal boundaries, not separate services that slowly drift apart. +`build` must stay defined as `compile` plus terminal persistence, not as another independent executable path. + +**Trade-offs:** +This keeps behavior consistent for callers, but it requires the stage boundaries and result contracts to be explicit. +Without explicit contracts, one shared pipeline easily collapses back into a mutable context API that callers misuse. + +### Make Terminal Stage Boundaries Part of the Public Contract + +**What:** +The entrypoints now mean: + +- `analyze = ResolveDeps + LoadSources + FrontendPhase` +- `compile = analyze + LowerToIRVM + OptimizeIRVM + EmitBytecode + LinkBytecode + VerifyBytecode` +- `build = compile + WriteBytecodeArtifact` + +**Why:** +The value is not just naming. +Each entrypoint now communicates a precise side-effect boundary and a precise result boundary. +That lets tooling consumers ask for semantic facts, executable callers ask for validated in-memory bytecode, and filesystem callers ask for persisted artifacts without inventing alternate pipeline semantics. + +**Trade-offs:** +The team must protect these boundaries with tests and conformance docs. +If callers start bypassing them with ad hoc helpers, `compile` and `build` drift immediately. + +### Publish Stable Result Contracts Instead of Leaking Mutable Pipeline Context + +**What:** +The public surface now returns stable record contracts: + +- `AnalysisSnapshot` +- `CompileResult` +- `BuildResult` + +**Why:** +`BuilderPipelineContext` is mutable internal state, not a good external contract. +Stable result models make the minimum payload explicit and keep callers from depending on incidental intermediate fields. + +**Trade-offs:** +This adds adapter code from pipeline context to public results. +That cost is worth paying because it limits public coupling and makes future multi-caller evolution safer. + +## Final Implementation + +The implementation landed across specs, code, and tests: + +- Chapter 23 in `docs/specs/compiler` now defines the canonical entrypoints and minimum result contracts. +- `BuilderPipelineService` now exposes `analyze`, `compile`, and `build` as the public surface. +- `Compile.main` now composes the default filesystem context and calls `build`. +- `AnalysisSnapshot`, `CompileResult`, and `BuildResult` carry the stable output contracts. +- integration coverage now proves that `analyze` and `compile` do not write `build/program.pbx`, while `build` does. + +## Examples + +- Use `analyze` when the caller needs diagnostics, source table access, workspace resolution, and frontend semantic facts for tooling. +- Use `compile` when the caller needs validated executable bytecode in memory and must not touch the filesystem. +- Use `build` when the caller wants the normal artifact-producing compiler behavior and a concrete `program.pbx` path. + +## Pitfalls + +- Do not reintroduce a public `run` alias. That would blur the side-effect boundary the discussion just made explicit. +- Do not let `build` diverge semantically from `compile`. The only extra step for `build` is terminal artifact persistence. +- Do not leak `BuilderPipelineContext` back into callsites as the real public contract. That would make the stable result models nominal only. +- Do not add caller-specific configs that silently change stage order or stage meaning under the names `analyze`, `compile`, or `build`. +- Do not treat `compile` as "half-build". It is a complete validated in-memory executable result, not an editorially weaker path. + +## References + +- `DEC-0007` Canonical compiler entrypoints for analyze, compile, and build +- `PLN-0009` Propagate DEC-0007 into compiler pipeline specs and public contracts +- `PLN-0010` Refactor BuilderPipelineService into explicit analyze, compile, and build entrypoints +- `PLN-0011` Migrate compiler callsites and tests to explicit build, compile, and analyze entrypoints +- `docs/specs/compiler/23. Compiler Pipeline Entry Points Specification.md` +- `docs/specs/compiler/22. Backend Spec-to-Test Conformance Matrix.md` +- `prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/workspaces/BuilderPipelineService.java` +- `prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/MainProjectPipelineIntegrationTest.java` + +## Takeaways + +- The durable pattern is one canonical compiler pipeline with explicit terminal entrypoints, not multiple near-duplicate pipelines. +- Side-effect boundaries are first-class API semantics: `analyze` and `compile` must stay no-write, and `build` is the only artifact-materialization path. +- Stable result contracts are part of the architectural fix; callers should consume `AnalysisSnapshot`, `CompileResult`, and `BuildResult`, not mutable pipeline internals. diff --git a/discussion/workflow/agendas/AGD-0011-compiler-analyze-compile-build-pipeline-split.md b/discussion/workflow/agendas/AGD-0011-compiler-analyze-compile-build-pipeline-split.md deleted file mode 100644 index a01423b6..00000000 --- a/discussion/workflow/agendas/AGD-0011-compiler-analyze-compile-build-pipeline-split.md +++ /dev/null @@ -1,194 +0,0 @@ ---- -id: AGD-0011 -ticket: compiler-analyze-compile-build-pipeline-split -title: Desacoplar o pipeline do compiler em analyze, compile e build -status: accepted -created: 2026-03-30 -resolved: 2026-03-30 -decision: DEC-0007 -tags: - - compiler - - pipeline - - artifacts - - build - - analysis ---- - -## Pain - -Hoje o pipeline principal do compiler exposto por `BuilderPipelineService` e monolitico: ele resolve dependencias, carrega fontes, roda frontend, lowering, otimizacao, emissao, verificacao e sempre termina escrevendo `build/program.pbx`. - -Isso acopla tres intencoes diferentes num unico fluxo: - -- analisar codigo e produzir diagnosticos/estado semantico; -- compilar ate um resultado executavel em memoria; -- materializar artefato final em disco. - -Esse acoplamento atrapalha diretamente o proximo wave do Studio editor e o futuro LSP: - -- o editor precisa de `analyze` sem forcar emissao de PBX; -- um consumidor de semantica pode precisar de `compile` em memoria sem write side effects; -- `build` deve continuar existindo como fluxo de artefato, mas nao como unica forma de usar o compiler. - -## Context - -Domain owner: `compiler` -Owner surface: `docs/specs/compiler` -Cross-domain input: `studio` - -Superficies relevantes hoje: - -- `prometeu-compiler/prometeu-build-pipeline/.../BuilderPipelineService.java` registra uma lista fixa de stages e sempre inclui `WriteBytecodeArtifactPipelineStage` no fim; -- `EmitBytecodePipelineStage` ja produz `ctx.bytecodeModule` e `ctx.bytecodeBytes` em memoria antes de qualquer write em disco; -- `WriteBytecodeArtifactPipelineStage` apenas persiste `build/program.pbx`, o que mostra que a emissao de artefato ja e uma preocupacao separavel; -- `docs/specs/compiler/15. Bytecode and PBX Mapping Specification.md` normatiza a fronteira de emissao PBX/bytecode, mas nao exige que todo consumo do compiler materialize artefato em disco; -- na discussion do editor (`DSC-0010`), ja ficou aceito que `SourceProviderFactory` sera mantido como boundary de leitura, com providers mais especificos no futuro para sessao documental do editor. -- embora PBS seja hoje o frontend mais avancado nesse caminho, esta agenda pertence ao dominio `compiler` e precisa preservar um contrato de pipeline frontend-agnostico, reutilizavel por PBS e por futuros FEs sem regressao no comportamento de `compile`. - -Boundary explicitamente fechado para esta agenda: - -- `SourceProviderFactory` continua sendo a fronteira de leitura do compiler; -- esta agenda NAO vai discutir ainda o novo provider do editor; -- esta agenda vai discutir apenas como expor `analyze`, `compile` e `build` como entradas distintas do compiler. -- o split do pipeline nao pode introduzir semantica especial de PBS na API operacional do compiler; compatibilidade com o `compile` atual de PBS deve ser tratada como restricao obrigatoria. - -## Open Questions - -- [x] Qual deve ser o corte exato entre `analyze` e `compile`: `analyze` para no frontend/diagnostics, ou inclui tambem lowering/backend facts uteis para tooling? - Recomendacao: `analyze` deve terminar em `FrontendPhasePipelineStage`, isto e, `ResolveDeps + LoadSources + FrontendPhase`, expondo diagnosticos e facts semanticos orientados a tooling sem avancar para lowering ou emissao. -- [x] `compile` deve ir ate `bytecodeModule`/`bytecodeBytes` em memoria sem write, ou deve parar em `IRVM` e deixar emissao para `build`? - Recomendacao: `compile` deve terminar em `VerifyBytecodePipelineStage`, produzindo `bytecodeModule` e `bytecodeBytes` verificados em memoria sem write side effects; parar em `IRVM` deixaria a superficie incompleta para consumidores que precisam de resultado executavel sem persistencia. -- [x] A verificacao (`VerifyBytecodePipelineStage`) pertence a `compile`, a `build`, ou a ambos conforme perfil? - Recomendacao: `VerifyBytecodePipelineStage` e o stage terminal de `compile`, e `build` apenas adiciona `WriteBytecodeArtifactPipelineStage` depois disso; `compile` nao deve devolver bytes nao verificados. -- [x] Como representar esses tres modos: services separados, perfis de pipeline, ou uma composicao explicita de stage groups? - Recomendacao: expor tres chamadas canonicas no mesmo pipeline compartilhado, por exemplo `analyze`, `compile` e `build`, evitando tanto tres pipelines independentes quanto um unico `run` monolitico com semantica implicita. -- [x] O resultado de `analyze` deve expor um `AnalysisSnapshot` estavel para editor/LSP, ou apenas diagnosticos + facts minimos no primeiro wave? - Recomendacao: `analyze` deve expor um `AnalysisSnapshot` estavel ja no primeiro wave, mas com shape minimo e pragmatico, carregando apenas os facts e handles necessarios para editor/LSP. -- [x] O CLI atual e os callsites existentes devem continuar mapeando `build` como comportamento default? - Recomendacao: sim; a mudanca deve ampliar a superficie operacional do compiler sem quebrar o comportamento default atual de artefato em disco. -- [x] Como evitar que `build` e `compile` passem a divergir semanticamente por ordem de stages ou gates diferentes? - Recomendacao: `build` deve ser definido normativamente como o mesmo fluxo de `compile`, encerrado por `WriteBytecodeArtifactPipelineStage`, sem reorder ou gates semanticos exclusivos fora da persistencia terminal. -- [x] LSP/editor devem usar outro pipeline, ou o mesmo pipeline com chamadas e contextos diferentes? - Recomendacao: devem usar o mesmo pipeline canonico, mas atraves de chamadas diferentes e configs/contextos distintos por entrypoint; mudar inputs, sinks e shape de resultado e valido, mas mudar a semantica central dos stages canonicos nao. -- [x] O `run` atual deve continuar existindo como alias, ou deve ser absorvido por `build`? - Recomendacao: `run` nao deve permanecer como entrypoint publico; o comportamento default de hoje deve ser absorvido por `build`, com contexto/config de filesystem construido fora do pipeline em si. -- [x] Quais contratos ou specs precisam receber propagacao quando o pipeline deixar de ter uma unica entrada monolitica? - Recomendacao: a propagacao principal deve atingir a spec operacional do pipeline do compiler, os contratos de CLI/callsites e a documentacao de resultados intermediarios; a spec de PBX continua authority de emissao, nao de persistencia em disco. - -## Options - -### Option A - Manter `BuilderPipelineService` monolitico e adicionar flags -- **Approach:** Preservar o pipeline atual e usar flags condicionais para pular write de artefato ou parar em stages intermediarios. -- **Pro:** Menor mudanca inicial. -- **Con:** Esconde perfis diferentes dentro de um fluxo ad hoc, torna os cortes menos legiveis e aumenta risco de combinacoes invalidas. -- **Maintainability:** Fraca. O comportamento fica implicito e espalhado por condicionais. - -### Option B - Definir tres entrypoints normativos sobre um pipeline composavel -- **Approach:** Modelar o pipeline como composicao reutilizavel de stage groups e expor tres modos canonicos: `analyze`, `compile` e `build`. -- **Pro:** Torna o contrato explicito, reaproveita as mesmas stages onde fizer sentido e separa claramente analise, compilacao em memoria e emissao de artefato. -- **Con:** Exige fechar com precisao o corte entre as fases e o shape dos resultados intermediarios. -- **Maintainability:** Forte. O compiler ganha uma superficie operacional clara para CLI, Studio, testes e LSP. - -### Option C - Separar services independentes por responsabilidade -- **Approach:** Criar services distintos e quase autossuficientes para `AnalyzeService`, `CompileService` e `BuildService`, cada um com seu proprio encadeamento. -- **Pro:** As responsabilidades ficam bem nomeadas. -- **Con:** Se a composicao nao for rigorosamente compartilhada, o risco de drift entre os fluxos cresce rapido. -- **Maintainability:** Media. Pode funcionar, mas so se a infraestrutura comum ficar bem centralizada. - -## Discussion - -O codigo atual ja mostra o seam principal que queremos aproveitar: - -1. primeiro o pipeline resolve e analisa a workspace; -2. depois produz artefatos executaveis em memoria; -3. por fim escreve `program.pbx` em disco. - -O problema nao e falta de separacao conceitual. -O problema e que essa separacao ainda nao virou API normativa nem entrypoints distintos. - -Para o editor e o LSP, isso importa muito: - -- `analyze` precisa ser barato em side effects e orientado a snapshot; -- `compile` precisa produzir um resultado coerente em memoria sem obrigar write de artefato; -- `build` precisa continuar sendo o fluxo que materializa `program.pbx`. - -Ao mesmo tempo, esta agenda nao deve misturar dois assuntos: - -- como o compiler le fontes; -- e como ele expõe seus perfis de execucao. - -O primeiro assunto fica travado: `SourceProviderFactory` continua sendo o boundary. -O segundo e o alvo desta discussion: desacoplar a intencao operacional do pipeline. - -Tambem precisamos manter a classificacao correta do problema: - -- PBS nao e o owner desta decisao; ele e um frontend consumidor importante; -- o split precisa servir ao compiler como plataforma multi-frontend; -- isso significa que a nova API de `analyze`/`compile`/`build` deve preservar o comportamento correto que o caminho atual ja entrega para PBS, sem acoplar o contrato a detalhes exclusivos desse frontend. - -Tambem fica fechado que LSP/editor nao introduzem "outro pipeline" no dominio `compiler`. -O que muda sao as chamadas e os contextos de execucao: - -- o pipeline canonico permanece unico; -- `analyze`, `compile` e `build` sao entrypoints distintos sobre esse mesmo pipeline; -- configs/contextos diferentes podem ajustar leitura, coletores, sinks e shape de retorno por caso de uso; -- esses contextos nao devem redefinir a semantica central dos stages canonicos. -- o comportamento default atual deixa de se chamar `run` e passa a ser o `build` construido com config/contexto de filesystem montado pelo callsite, nao pelo pipeline em si. - -A direcao mais saudavel parece ser explicitar tres perfis canonicos: - -1. `analyze` - termina em `FrontendPhasePipelineStage`, isto e, resolve deps, carrega fontes, roda frontend e produz `AnalysisSnapshot` com diagnosticos e facts semanticos sem executar lowering, emissao ou write de artefato. -2. `compile` - termina em `VerifyBytecodePipelineStage`, isto e, reaproveita o mesmo eixo semantico de `analyze`, avanca por lowering, otimizacao, emissao, link precheck e verificacao preload, e produz resultado executavel validado em memoria sem escrever arquivo. -3. `build` - termina em `WriteBytecodeArtifactPipelineStage`, isto e, e definido como `compile` seguido apenas da etapa terminal de materializacao do artefato em disco. - -Isso preserva um unico eixo semantico e reduz o risco de o Studio ou o LSP precisarem inventar um "mini-compiler" paralelo. - -Em termos de superficie de servico, o caminho recomendado elimina `run` como entrypoint normativo. -O servico deve passar a expor entrypoints explicitos, por exemplo: - -- `analyze(config, logs)` ou equivalente; -- `compile(config, logs)` ou equivalente; -- `build(config, logs)` ou equivalente. - -Cada chamada pode receber config/contexto apropriado ao caso de uso, mas continua percorrendo o mesmo pipeline canonico ate o stage terminal definido para aquele entrypoint. -O comportamento que hoje existe em `run` deve ser reexpresso como `build(filesystem-config, logs)` ou equivalente, com a construcao do contexto default acontecendo fora do pipeline itself. - -Fechamentos recomendados para a decisao: - -1. `analyze` termina em `FrontendPhasePipelineStage` e nao inclui lowering/backend execution artifacts. -2. `compile` termina em `VerifyBytecodePipelineStage` e vai ate `bytecodeModule` e `bytecodeBytes` em memoria. -3. `compile` inclui `LinkBytecode` e `VerifyBytecode` para que o resultado em memoria ja seja semanticamente confiavel. -4. `build` termina em `WriteBytecodeArtifactPipelineStage`; ele nao recompila por outro caminho e apenas reaproveita `compile` com a persistencia terminal. -5. a API publica deve expor snapshots/resultados estaveis por perfil, sem vazar `BuilderPipelineContext` como contrato externo. -6. o CLI e os callsites existentes continuam apontando para `build` como comportamento default. -7. a decisao deve preservar compatibilidade comportamental com o `compile` atual usado por PBS, tratando esse fluxo como baseline de corretude e nao como detalhe descartavel de um frontend especifico. -8. a superficie nova deve permanecer frontend-agnostica, para que futuros FEs possam reutilizar o mesmo contrato sem herdar semantica acidental de PBS. -9. `BuilderPipelineService` nao deve manter `run` como entrypoint publico; ele deve expor `analyze`, `compile` e `build` sobre o mesmo pipeline compartilhado. -10. o comportamento atual de `run` deve ser absorvido por `build` com config/contexto de filesystem construido fora do pipeline em si. -11. configs/contextos distintos por entrypoint sao permitidos para suportar CLI, editor e LSP, desde que nao alterem a semantica central dos stages canonicos. - -## Resolution - -Recommended direction: seguir com **Option B**. - -A agenda deve convergir para uma decisao com os seguintes fechamentos: - -1. `SourceProviderFactory` permanece como boundary de leitura do compiler; -2. o compiler deve expor tres entrypoints normativos: `analyze`, `compile` e `build`; -3. `build` nao e mais sinonimo de "todo uso do compiler", mas apenas o perfil que materializa artefato; -4. `analyze` deve ser definido como o perfil que termina em `FrontendPhasePipelineStage`, isto e, `ResolveDeps + LoadSources + FrontendPhase`, retornando `AnalysisSnapshot` estavel e sem write side effects; -5. `compile` deve ser definido como o perfil que termina em `VerifyBytecodePipelineStage`, isto e, `analyze + LowerToIRVM + OptimizeIRVM + EmitBytecode + LinkBytecode + VerifyBytecode`, retornando resultado validado em memoria; -6. `build` deve ser definido como o perfil que termina em `WriteBytecodeArtifactPipelineStage`, isto e, `compile + WriteBytecodeArtifact`, sem reorder semantico ou gates adicionais fora da persistencia terminal; -7. a API publica deve retornar resultados estaveis por perfil em vez de expor o `BuilderPipelineContext` diretamente; -8. o CLI/build atual deve continuar como comportamento default para compatibilidade; -9. a decisao deve preservar compatibilidade comportamental com o `compile` atual de PBS como baseline de corretude, sem transformar PBS em detalhe normativo do contrato publico; -10. a superficie `analyze`/`compile`/`build` deve permanecer frontend-agnostica para acomodar multiplos FEs no dominio `compiler`; -11. `BuilderPipelineService` deve remover `run` como entrypoint publico e expor `analyze`, `compile` e `build`, cada um com config/contexto apropriado ao seu caso de uso; -12. o comportamento default de hoje deve ser preservado como `build` com config/contexto de filesystem, construido fora do pipeline itself; -13. configs/contextos diferentes por entrypoint sao parte do modelo, mas nao podem redefinir a semantica central dos stages canonicos; -14. a propagacao deve atingir a spec operacional do pipeline, os contratos de CLI/callsites e a documentacao dos resultados intermediarios, preservando a spec de PBX como authority de emissao. - -Next step suggestion: converter esta agenda em uma `decision` que feche o stage boundary de cada perfil, o contrato dos resultados intermediarios e a compatibilidade do CLI/build atual com o novo modelo. diff --git a/discussion/workflow/decisions/DEC-0007-compiler-analyze-compile-build-pipeline-split.md b/discussion/workflow/decisions/DEC-0007-compiler-analyze-compile-build-pipeline-split.md deleted file mode 100644 index 665b0a03..00000000 --- a/discussion/workflow/decisions/DEC-0007-compiler-analyze-compile-build-pipeline-split.md +++ /dev/null @@ -1,164 +0,0 @@ ---- -id: DEC-0007 -ticket: compiler-analyze-compile-build-pipeline-split -title: Canonical compiler entrypoints for analyze, compile, and build -status: in_progress -created: 2026-03-30 -accepted: 2026-03-30 -agenda: AGD-0011 -plans: - - PLN-0009 - - PLN-0010 - - PLN-0011 -tags: - - compiler - - pipeline - - artifacts - - build - - analysis ---- - -## Decision - -O dominio `compiler` SHALL expor tres entrypoints canonicos sobre um unico pipeline compartilhado: - -1. `analyze` -2. `compile` -3. `build` - -Esses entrypoints MUST corresponder aos seguintes cortes normativos de stages: - -1. `analyze = ResolveDeps + LoadSources + FrontendPhase` -2. `compile = analyze + LowerToIRVM + OptimizeIRVM + EmitBytecode + LinkBytecode + VerifyBytecode` -3. `build = compile + WriteBytecodeArtifact` - -`BuilderPipelineService` MUST deixar de expor `run` como entrypoint publico. -O comportamento atualmente observado em `run` MUST ser preservado como o comportamento default de `build`, usando config/contexto de filesystem construido fora do pipeline em si. - -LSP, editor e outros consumidores MUST reutilizar esse mesmo pipeline canonico. -Eles MAY fornecer configs/contextos distintos por entrypoint, mas esses contextos MUST NOT alterar a semantica central dos stages canonicos nem introduzir um pipeline paralelo disfarçado. - -## Rationale - -O pipeline atual ja possui um seam natural entre: - -1. analise semantica da workspace; -2. producao de artefato executavel em memoria; -3. persistencia terminal em disco. - -Transformar esses cortes em entrypoints explicitos melhora a superficie operacional do compiler sem duplicar infraestrutura nem esconder semantica em flags ad hoc. - -Essa decisao tambem preserva duas propriedades importantes: - -1. compatibilidade comportamental com o fluxo atual que produz artefato executavel para PBS, que passa a ser tratado como baseline de corretude; -2. generalidade suficiente para que outros frontends consumam o compiler sem herdarem regras exclusivas de PBS. - -Remover `run` evita que o nome antigo continue funcionando como conceito normativo opaco. -O nome correto do fluxo default passa a ser `build`. - -## Technical Specification - -### 1. Canonical pipeline - -O compiler MUST manter um unico pipeline canonico compartilhado. -Esse pipeline MUST preservar a semantica e a ordem dos stages normativos: - -1. `ResolveDepsPipelineStage` -2. `LoadSourcesPipelineStage` -3. `FrontendPhasePipelineStage` -4. `LowerToIRVMPipelineStage` -5. `OptimizeIRVMPipelineStage` -6. `EmitBytecodePipelineStage` -7. `LinkBytecodePipelineStage` -8. `VerifyBytecodePipelineStage` -9. `WriteBytecodeArtifactPipelineStage` - -Nenhum entrypoint MAY reordenar esses stages. - -### 2. Entry point contracts - -`analyze` MUST terminar em `FrontendPhasePipelineStage`. -`analyze` MUST retornar um `AnalysisSnapshot` estavel ou equivalente de mesmo papel semantico. -Esse resultado MUST expor, no minimo: - -1. diagnosticos; -2. facts semanticos produzidos pelo frontend; -3. referencias estaveis para os sources carregados, incluindo o equivalente ao `FileTable`; -4. metadados de resolucao da workspace necessarios para tooling. - -Implementacoes MAY expor campos adicionais, mas MUST NOT omitir esses elementos minimos. -`analyze` MUST NOT executar lowering, emissao, verificacao de bytecode ou persistencia de artefato. - -`compile` MUST terminar em `VerifyBytecodePipelineStage`. -`compile` MUST produzir resultado executavel validado em memoria, incluindo `bytecodeModule` e `bytecodeBytes` ou equivalentes de mesmo papel semantico. -`compile` MUST incluir `LinkBytecode` e `VerifyBytecode`. -`compile` MUST NOT persistir artefato em disco. - -`build` MUST terminar em `WriteBytecodeArtifactPipelineStage`. -`build` MUST ser definido como `compile` seguido apenas da persistencia terminal. -`build` MUST preservar o comportamento default atual de escrita de artefato em filesystem. - -### 3. Service surface - -`BuilderPipelineService` MUST evoluir para uma superficie com entrypoints explicitos equivalentes a: - -1. `analyze(config, logs)` -2. `compile(config, logs)` -3. `build(config, logs)` - -Os nomes exatos MAY variar, mas a separacao semantica MUST ser preservada. - -`run` MUST ser removido como entrypoint publico. -Qualquer composicao equivalente ao comportamento atual MUST ser expressa por `build` com config/contexto apropriado. - -### 4. Context and config model - -Configs/contextos distintos por entrypoint MAY existir para suportar CLI, editor, LSP e outros callsites. - -Esses contextos MAY ajustar: - -1. fontes de entrada; -2. sinks/collectors; -3. shape de retorno; -4. estrategia de composicao externa. - -Esses contextos MUST NOT: - -1. redefinir a semantica central dos stages canonicos; -2. introduzir ordem diferente de stages para os mesmos entrypoints; -3. criar um pipeline paralelo com regras semanticas proprias sob os mesmos nomes `analyze`, `compile` ou `build`. - -A construcao do contexto default de filesystem MUST acontecer fora do pipeline itself, no callsite ou camada de composicao apropriada. - -### 5. Compatibility and propagation - -Esta decisao MUST preservar compatibilidade comportamental com o fluxo atual que produz artefato executavel para PBS. -Essa compatibilidade MUST cobrir, no minimo: - -1. a mesma ordem semantica de stages hoje usada para chegar ao artefato executavel; -2. o mesmo nivel de corretude do resultado executavel produzido em memoria antes da persistencia; -3. a ausencia de regressao nos gates de emissao, link e verificacao que hoje protegem esse fluxo. - -PBS MUST ser tratado como consumidor importante e baseline de corretude, mas MUST NOT virar detalhe normativo exclusivo da API publica. - -Esta decisao MUST ser propagada para: - -1. a spec operacional do pipeline do compiler; -2. os contratos de CLI e callsites existentes; -3. a documentacao dos resultados intermediarios (`AnalysisSnapshot`, resultado de `compile`, resultado de `build`). - -Esta decisao MUST NOT reinterpretar a spec de PBX como requisito de persistencia em disco. -A authority da spec de PBX permanece na fronteira de emissao e mapeamento de artefatos. - -## Constraints - -1. `SourceProviderFactory` permanece como boundary de leitura do compiler nesta decisao. -2. Esta decisao nao define ainda novos providers especificos de editor. -3. Esta decisao nao autoriza pipelines paralelos por frontend. -4. Esta decisao nao permite tratar requisito normativo aqui definido como opcional em plan ou implement. -5. Qualquer revisao futura sobre os cortes de stage, o modelo de contexto ou a remocao de `run` MUST ocorrer por nova decisao explicita. - -## Revision Log - -- 2026-03-30: Initial draft from AGD-0011. -- 2026-03-30: Accepted and decomposed into PLN-0009, PLN-0010, and PLN-0011. diff --git a/discussion/workflow/plans/PLN-0009-compiler-pipeline-spec-and-contract-propagation.md b/discussion/workflow/plans/PLN-0009-compiler-pipeline-spec-and-contract-propagation.md deleted file mode 100644 index a975bed2..00000000 --- a/discussion/workflow/plans/PLN-0009-compiler-pipeline-spec-and-contract-propagation.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -id: PLN-0009 -ticket: compiler-analyze-compile-build-pipeline-split -title: Propagate DEC-0007 into compiler pipeline specs and public contracts -status: done -created: 2026-03-30 -completed: 2026-03-30 -tags: - - compiler - - pipeline - - specs - - contracts ---- - -## Objective - -Propagate DEC-0007 into the normative compiler spec surface so that `analyze`, `compile`, and `build` become explicit operational contracts before code migration starts. - -## Background - -DEC-0007 locks one canonical pipeline with three entrypoints, removes `run` as a public concept, requires a minimum `AnalysisSnapshot` contract, and requires propagation into compiler specs and callsite-facing documentation. - -The current shared compiler spec set contains backend and conformance chapters, but it does not yet define canonical compiler entrypoints or their result contracts as first-class normative surfaces. - -## Scope - -### Included -- Add or update shared compiler specs to define `analyze`, `compile`, and `build`. -- Document the minimum required shape of `AnalysisSnapshot`, the compile result, and the build result. -- Update compiler spec navigation and cross-references so DEC-0007 becomes discoverable from the shared spec surface. -- Update conformance-facing documentation to reflect entrypoint-specific expectations. - -### Excluded -- Java implementation changes in `prometeu-build-pipeline`. -- Editor or LSP callsite integration work. -- Removal of legacy Java APIs by itself. - -## Execution Steps - -### Step 1 - Add canonical compiler entrypoint specification - -**What:** Introduce a new shared compiler spec chapter that defines the canonical pipeline, the terminal stage for each entrypoint, and the mandatory result contracts. -**How:** Create a new chapter under `docs/specs/compiler/` covering: -1. canonical stage order, -2. `analyze = ResolveDeps + LoadSources + FrontendPhase`, -3. `compile = analyze + LowerToIRVM + OptimizeIRVM + EmitBytecode + LinkBytecode + VerifyBytecode`, -4. `build = compile + WriteBytecodeArtifact`, -5. minimum `AnalysisSnapshot` surface, -6. validated in-memory compile result contract, -7. filesystem build contract, -8. removal of `run` as a public entrypoint. -**File(s):** -- `docs/specs/compiler/README.md` -- `docs/specs/compiler/23. Compiler Pipeline Entry Points Specification.md` - -### Step 2 - Align conformance-facing shared docs - -**What:** Update shared compiler conformance documentation to refer to entrypoint contracts rather than one monolithic build invocation. -**How:** Extend the existing conformance matrix and any related shared references so tests can be mapped to `analyze`, `compile`, and `build` responsibilities separately, including stage-boundary assertions and artifact-side-effect boundaries. -**File(s):** -- `docs/specs/compiler/22. Backend Spec-to-Test Conformance Matrix.md` - -### Step 3 - Document migration expectations for callsites - -**What:** State the public migration rule that current default filesystem behavior is now expressed through `build`, not `run`. -**How:** Capture, in the new or updated spec text, that: -1. `run` is not a normative public entrypoint, -2. filesystem-default composition happens outside the pipeline itself, -3. CLI and other callsites must migrate to explicit entrypoints. -**File(s):** -- `docs/specs/compiler/23. Compiler Pipeline Entry Points Specification.md` -- `docs/specs/compiler/README.md` - -## Test Requirements - -### Unit Tests - -- No Java unit tests are required for this editorial plan. - -### Integration Tests - -- No runtime integration tests are required for this editorial plan. - -### Manual Verification - -- Verify the new chapter is reachable from `docs/specs/compiler/README.md`. -- Verify the new chapter uses the exact DEC-0007 stage boundaries and does not reintroduce `run`. -- Verify the conformance matrix distinguishes analysis, in-memory compile, and filesystem build responsibilities. - -## Acceptance Criteria - -- [ ] Shared compiler specs explicitly define `analyze`, `compile`, and `build` as the canonical entrypoints. -- [ ] The minimum `AnalysisSnapshot` contract is written normatively in the shared compiler spec surface. -- [ ] The shared docs state that `run` is removed as a public entrypoint and that filesystem-default composition belongs outside the pipeline. -- [ ] Conformance-facing documentation reflects entrypoint-specific obligations rather than a single monolithic pipeline invocation. - -## Dependencies - -- DEC-0007 accepted content. -- No code implementation dependency is required before this plan can start. - -## Risks - -- A too-editorial-only writeup may drift from the exact Java module boundaries that later code work needs. -- If the result contracts are written loosely, the implementation plans may inherit avoidable ambiguity. diff --git a/discussion/workflow/plans/PLN-0010-refactor-builder-pipeline-service-into-entrypoints.md b/discussion/workflow/plans/PLN-0010-refactor-builder-pipeline-service-into-entrypoints.md deleted file mode 100644 index 34fff940..00000000 --- a/discussion/workflow/plans/PLN-0010-refactor-builder-pipeline-service-into-entrypoints.md +++ /dev/null @@ -1,124 +0,0 @@ ---- -id: PLN-0010 -ticket: compiler-analyze-compile-build-pipeline-split -title: Refactor BuilderPipelineService into explicit analyze, compile, and build entrypoints -status: done -created: 2026-03-30 -completed: 2026-03-30 -tags: - - compiler - - pipeline - - implementation - - api ---- - -## Objective - -Implement the canonical pipeline entrypoints from DEC-0007 in `prometeu-build-pipeline`, replacing the monolithic public `run` surface with explicit `analyze`, `compile`, and `build` operations. - -## Background - -The current `BuilderPipelineService` exposes one public `run(config, logs)` entrypoint and internally constructs a filesystem-anchored `BuilderPipelineContext`. - -DEC-0007 requires: -1. one canonical pipeline with fixed stage ordering, -2. `analyze`, `compile`, and `build` as explicit public entrypoints, -3. stable result contracts rather than leaking `BuilderPipelineContext`, -4. filesystem-default context construction outside the pipeline itself. - -## Scope - -### Included -- Refactor `BuilderPipelineService` public API to explicit entrypoints. -- Introduce stable result models for `analyze`, `compile`, and `build`. -- Refactor context/config construction so filesystem-default composition is no longer hardcoded inside the pipeline service. -- Keep the canonical stage ordering unchanged. - -### Excluded -- Updating downstream callsites and tests outside the core pipeline module. -- Editor/LSP-specific consumers beyond the generic context/config model. -- Housekeeping deletion of historical docs or discussion artifacts. - -## Execution Steps - -### Step 1 - Introduce explicit result contracts - -**What:** Add stable result types for each public entrypoint so the service no longer exposes `BuilderPipelineContext` as the external contract. -**How:** Define result models with the minimum DEC-0007 requirements: -1. `AnalysisSnapshot` or equivalent for `analyze`, -2. an in-memory compile result carrying validated executable artifacts for `compile`, -3. a build result carrying the persisted artifact location and compile payload for `build`. -Keep internal mutable pipeline state in `BuilderPipelineContext`, but add explicit adapters from context to public result objects. -**File(s):** -- `prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/models/BuilderPipelineContext.java` -- `prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/messages/` -- `prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/models/` - -### Step 2 - Split service entrypoints by terminal stage - -**What:** Refactor `BuilderPipelineService` so each public entrypoint stops at the DEC-0007 terminal stage. -**How:** Replace the public `run` flow with explicit methods that execute the same canonical stage list through bounded terminal stages: -1. `analyze` stops after `FrontendPhasePipelineStage`, -2. `compile` stops after `VerifyBytecodePipelineStage`, -3. `build` stops after `WriteBytecodeArtifactPipelineStage`. -Use one shared stage execution helper so the implementation does not fork stage order or error handling logic across entrypoints. -**File(s):** -- `prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/workspaces/BuilderPipelineService.java` -- `prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/workspaces/PipelineStage.java` - -### Step 3 - Externalize context construction - -**What:** Remove the implicit filesystem-default context construction from inside the pipeline service. -**How:** Refactor `BuilderPipelineContext.compilerContext(...)` and surrounding config flow so entrypoints receive the context/config composition required for their caller. -Preserve filesystem support, but move its construction into explicit factories or caller-side composition helpers rather than hardcoding it as the only pipeline-owned mode. -**File(s):** -- `prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/models/BuilderPipelineContext.java` -- `prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/messages/BuilderPipelineConfig.java` -- `prometeu-compiler/prometeu-compiler-core/src/main/java/p/studio/compiler/utilities/SourceProviderFactory.java` - -### Step 4 - Keep canonical stage behavior intact - -**What:** Ensure the refactor preserves the semantic order and gating behavior of the current executable pipeline. -**How:** Keep the stage order fixed, preserve current error propagation, and ensure `compile` still covers lowering, optimization, emission, link precheck, and verification before any build-specific artifact write occurs. -**File(s):** -- `prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/workspaces/BuilderPipelineService.java` -- `prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/workspaces/stages/*.java` - -## Test Requirements - -### Unit Tests - -- Add service-level tests proving each entrypoint stops at its required terminal stage. -- Add tests proving `analyze` produces the minimum snapshot contract and does not populate backend artifact outputs. -- Add tests proving `compile` returns validated in-memory artifacts without writing to disk. -- Add tests proving `build` extends `compile` only with artifact persistence. - -### Integration Tests - -- Preserve or replace the existing end-to-end pipeline integration coverage with explicit `build`-based integration tests. -- Add an integration test that exercises `compile` against a real project root and asserts no artifact file is written. - -### Manual Verification - -- Inspect the public API of `BuilderPipelineService` to confirm `run` is gone. -- Verify the default filesystem composition is not hardcoded as the only context path inside the service. -- Verify stage order remains unchanged from DEC-0007. - -## Acceptance Criteria - -- [ ] `BuilderPipelineService` exposes explicit `analyze`, `compile`, and `build` entrypoints and no longer exposes public `run`. -- [ ] Public result types exist and `BuilderPipelineContext` is no longer the external contract. -- [ ] `analyze`, `compile`, and `build` stop exactly at the DEC-0007 terminal stages. -- [ ] Filesystem-default behavior is still supported but is composed outside the pipeline core. -- [ ] The canonical executable path preserves current PBS-facing correctness through emit, link, and verify. - -## Dependencies - -- PLN-0009 should land first or in parallel if the spec wording is stable. -- No downstream callsite migration should begin until the new entrypoints and result models exist. - -## Risks - -- Refactoring context ownership without a clear composition boundary can accidentally leave filesystem behavior embedded in the service. -- Result models that mirror the mutable context too closely will leak internal implementation details back into the public API. -- If stage slicing is duplicated per method instead of shared, drift between `compile` and `build` can reappear immediately. diff --git a/discussion/workflow/plans/PLN-0011-migrate-callsites-and-tests-to-build-compile-analyze.md b/discussion/workflow/plans/PLN-0011-migrate-callsites-and-tests-to-build-compile-analyze.md deleted file mode 100644 index d9ec3f02..00000000 --- a/discussion/workflow/plans/PLN-0011-migrate-callsites-and-tests-to-build-compile-analyze.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -id: PLN-0011 -ticket: compiler-analyze-compile-build-pipeline-split -title: Migrate compiler callsites and tests to explicit build, compile, and analyze entrypoints -status: done -created: 2026-03-30 -completed: 2026-03-30 -tags: - - compiler - - pipeline - - migration - - tests ---- - -## Objective - -Migrate existing compiler callsites and test coverage away from `run` so the codebase consumes the DEC-0007 entrypoints explicitly and preserves current filesystem build behavior under `build`. - -## Background - -The current public caller in `prometeu-build-pipeline` is `Compile.main`, which constructs `BuilderPipelineConfig` and calls `BuilderPipelineService.INSTANCE.run(...)`. - -The test suite also includes service-level and integration coverage that still assumes a monolithic `run` entrypoint or a filesystem-default context built inside the pipeline service. - -DEC-0007 requires the default behavior to survive as `build`, with filesystem context composed outside the pipeline itself. - -## Scope - -### Included -- Replace production and test callsites that invoke the old `run` entrypoint. -- Preserve current CLI/default build behavior under explicit `build`. -- Add regression tests for side-effect boundaries between `analyze`, `compile`, and `build`. - -### Excluded -- The core service refactor itself. -- Language/frontend-specific editor or LSP consumers that do not yet exist in this codebase. -- Spec writing beyond what is covered in PLN-0009. - -## Execution Steps - -### Step 1 - Migrate the default CLI/build caller - -**What:** Update the current compiler entrypoint so it performs an explicit `build` call rather than a generic `run`. -**How:** Refactor `Compile.main` and any supporting composition helpers so the default filesystem-oriented config/context is assembled before invoking `build`. -Keep the effective behavior identical to the current default run mode. -**File(s):** -- `prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/Compile.java` -- `prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/messages/BuilderPipelineConfig.java` - -### Step 2 - Replace legacy service consumers in tests - -**What:** Update all service-level and integration tests that still call `BuilderPipelineService.INSTANCE.run(...)`. -**How:** Rewrite tests to target the explicit entrypoint they actually mean: -1. end-to-end artifact production tests use `build`, -2. in-memory executable tests use `compile`, -3. analysis-only tests use `analyze`. -Where the old tests only asserted canonical stage order or successful artifact write, preserve the same behavior under the new API names. -**File(s):** -- `prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/MainProjectPipelineIntegrationTest.java` -- `prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/workspaces/BuilderPipelineServiceOrderTest.java` -- `prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/workspaces/**/*.java` - -### Step 3 - Add regression coverage for side-effect boundaries - -**What:** Add explicit regression tests that enforce the no-write guarantees and terminal-stage boundaries required by DEC-0007. -**How:** Add tests that prove: -1. `analyze` does not execute backend artifact stages, -2. `compile` does not write `build/program.pbx`, -3. `build` writes the artifact and preserves current filesystem behavior, -4. removal of `run` does not reduce PBS-facing executable correctness. -**File(s):** -- `prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/` -- `prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/workspaces/` - -## Test Requirements - -### Unit Tests - -- Update any unit tests that instantiate the service or reason about stage execution to use explicit entrypoints. -- Add focused assertions for entrypoint-specific side effects and outputs. - -### Integration Tests - -- Preserve the existing artifact-producing integration behavior under `build`. -- Add at least one integration path that exercises `compile` and asserts artifact absence on disk. -- Add at least one analysis path that exercises `analyze` and verifies the minimum snapshot contract. - -### Manual Verification - -- Confirm there are no remaining production uses of `BuilderPipelineService.INSTANCE.run(...)`. -- Confirm the default CLI path still writes the expected artifact to the same build location. -- Confirm integration coverage still protects the PBS executable path. - -## Acceptance Criteria - -- [ ] No production callsite still invokes public `run`. -- [ ] Existing default filesystem behavior is preserved under explicit `build`. -- [ ] Tests explicitly distinguish `analyze`, `compile`, and `build`. -- [ ] Regression coverage exists for the no-write boundary of `compile` and the no-backend boundary of `analyze`. -- [ ] The migrated test suite still protects PBS-facing executable correctness. - -## Dependencies - -- PLN-0010 must land first because the new public entrypoints and result contracts must exist before callsite migration. -- PLN-0009 should land before or alongside this plan so naming and contracts match the normative docs. - -## Risks - -- Test migration can accidentally preserve old semantics by mechanically renaming `run` without asserting the new side-effect boundaries. -- If the CLI/default caller keeps assembling filesystem behavior inside the pipeline service, DEC-0007 will be implemented only nominally. -- Weak regression coverage here would allow `compile` and `build` to drift again after the refactor. diff --git a/docs/specs/compiler/22. Backend Spec-to-Test Conformance Matrix.md b/docs/specs/compiler/22. Backend Spec-to-Test Conformance Matrix.md index 5094ca69..2cbb6586 100644 --- a/docs/specs/compiler/22. Backend Spec-to-Test Conformance Matrix.md +++ b/docs/specs/compiler/22. Backend Spec-to-Test Conformance Matrix.md @@ -67,13 +67,13 @@ to concrete positive/negative test evidence and current status. | G21-9.1 | Validation MUST include optimized-vs-non-optimized equivalence fixtures. | `OptimizeIRVMEquivalenceHarnessTest#optimizeOnOffMustPreserveObservableTraceForLoweredHostIntrinsicFixture`; `OptimizeIRVMEquivalenceHarnessTest#optimizeOnOffMustPreserveObservableTraceForConditionalJoinFixture`; `OptimizeIRVMEquivalenceHarnessTest#optimizeOnOffMustPreserveObservableTraceForSimpleLoopFixture`; `OptimizeIRVMEquivalenceHarnessTest#optimizeOnOffMustPreserveObservableTraceForLinearCallFixture` | N/A | pass | Dedicated opt on/off harness with reusable interpreter and deterministic trace assertions is in place. | | G21-9.2 | Validation MUST preserve known negative loader/verifier behavior. | `BackendSafetyGateSUTest#emitStageMustExposeMarshalingLinkageFailureDeterministically`; `BackendGateIIntegrationTest` rejection suite | N/A | pass | | | G21-9.3 | Validation MUST preserve deterministic artifact-level invariants. | `BackendSafetyGateSUTest#fullPipelineMustProduceDeterministicBytecodeForSameInput`; `BytecodeEmitterTest#emitMustRemainDeterministicAfterInterning` | N/A | pass | | -| G23-5.1 | Canonical compiler pipeline MUST preserve the shared stage order through `WriteBytecodeArtifact`. | `BuilderPipelineServiceOrderTest#canonicalOrderMustContainOptimizeBetweenLowerAndEmit` | N/A | partial | Current evidence covers the shared order through optimize/emission boundaries; explicit write-stage and entrypoint-boundary coverage still needs implementation. | -| G23-6.1 | `analyze` MUST terminate after `FrontendPhase` and MUST NOT execute backend artifact stages. | N/A | N/A | missing | DEC-0007 and Chapter 23 are accepted; executable evidence will be added when explicit `analyze` entrypoint exists. | -| G23-6.2 | `compile` MUST terminate after `VerifyBytecode` and MUST return a validated in-memory executable result without disk write. | N/A | N/A | missing | Requires explicit service-level and integration coverage after entrypoint refactor. | -| G23-6.3 | `build` MUST extend `compile` only with terminal artifact persistence. | `MainProjectPipelineIntegrationTest#shouldCompileMainProjectAndWriteProgramBytecode` | N/A | partial | Existing build-path evidence predates the public `build` name and still needs migration to the explicit entrypoint API. | -| G23-7.1 | `AnalysisSnapshot` MUST expose the minimum shared analysis contract. | N/A | N/A | missing | No executable contract object exists yet. | +| G23-5.1 | Canonical compiler pipeline MUST preserve the shared stage order through `WriteBytecodeArtifact`. | `MainProjectPipelineIntegrationTest#analyzeShouldNotWriteProgramBytecode`; `MainProjectPipelineIntegrationTest#compileShouldProduceInMemoryBytecodeWithoutWritingProgramBytecode`; `MainProjectPipelineIntegrationTest#buildShouldWriteProgramBytecode` | N/A | partial | Entrypoint execution now covers the full analyze -> compile -> build path, but a dedicated order-only assertion for every terminal boundary is still missing. | +| G23-6.1 | `analyze` MUST terminate after `FrontendPhase` and MUST NOT execute backend artifact stages. | `MainProjectPipelineIntegrationTest#analyzeShouldNotWriteProgramBytecode` | N/A | pass | The integration fixture asserts the analysis snapshot contract and proves `program.pbx` is not written on the analysis path. | +| G23-6.2 | `compile` MUST terminate after `VerifyBytecode` and MUST return a validated in-memory executable result without disk write. | `MainProjectPipelineIntegrationTest#compileShouldProduceInMemoryBytecodeWithoutWritingProgramBytecode`; `BuilderPipelinePublicSurfaceTest#compileResultMustExposeValidatedInMemoryArtifacts` | N/A | pass | Coverage asserts validated in-memory bytecode artifacts and the no-write boundary for `compile`. | +| G23-6.3 | `build` MUST extend `compile` only with terminal artifact persistence. | `MainProjectPipelineIntegrationTest#buildShouldWriteProgramBytecode`; `BuilderPipelinePublicSurfaceTest#buildResultMustExposeArtifactPathAndCompilePayload` | N/A | pass | Coverage asserts that `build` retains the compile payload and writes the filesystem artifact path expected by callers. | +| G23-7.1 | `AnalysisSnapshot` MUST expose the minimum shared analysis contract. | `MainProjectPipelineIntegrationTest#analyzeShouldNotWriteProgramBytecode`; `BuilderPipelinePublicSurfaceTest#analysisSnapshotMustExposeMinimumSharedContract` | N/A | pass | Both executable and structural contract checks now cover the shared minimum analysis payload. | | G23-8.1 | Caller-specific configs/contexts MUST NOT redefine canonical stage semantics. | N/A | N/A | missing | Requires explicit multi-entrypoint composition tests once non-filesystem contexts are implemented. | -| G23-9.1 | Legacy public `run` MUST be removed as the normative entrypoint and filesystem-default behavior MUST be expressed through `build`. | N/A | N/A | missing | Requires callsite migration and public API refactor. | +| G23-9.1 | Legacy public `run` MUST be removed as the normative entrypoint and filesystem-default behavior MUST be expressed through `build`. | `BuilderPipelinePublicSurfaceTest#publicServiceSurfaceMustExposeExplicitEntrypointsAndNoPublicRun`; `MainProjectPipelineIntegrationTest#buildShouldWriteProgramBytecode` | N/A | partial | Public service coverage now proves `run` is no longer public and `build` is the filesystem artifact path, but the CLI composition path is not yet exercised by a dedicated automated test. | | PBS13-12.0 | Executable backend handoff MUST satisfy addendum obligations. | `IRBackendExecutableContractTest` suite; `PBSFrontendPhaseServiceTest#shouldSynthesizePositiveTopic19FixtureAcrossFileInitProjectInitAndFrame` | `LowerToIRVMServiceTest#lowerMustRejectWhenSyntheticWrapperEntrypointIsMissing`; `LowerToIRVMServiceTest#lowerMustRejectWhenHiddenBootGuardIsMissing`; `LowerToIRVMServiceTest#lowerMustRejectWhenSyntheticCallableOriginIsMissing` | pass | Row group `PBS13-12.x` details each obligation; topic 19 closure now includes lifecycle wrapper/guard/origin evidence. | | PBS13-12.1.1 | Callable identity MUST be preserved at handoff. | `IRBackendExecutableContractTest#aggregatorMustPreserveExecutableFunctionOrderDeterministically` | N/A | pass | | | PBS13-12.1.2 | Observable callable signature MUST be preserved at handoff. | `IRBackendExecutableContractTest#functionContractMustRejectInvalidSlotAndSpanBounds` | N/A | pass | | diff --git a/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/workspaces/BuilderPipelinePublicSurfaceTest.java b/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/workspaces/BuilderPipelinePublicSurfaceTest.java new file mode 100644 index 00000000..3659f0a4 --- /dev/null +++ b/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/workspaces/BuilderPipelinePublicSurfaceTest.java @@ -0,0 +1,63 @@ +package p.studio.compiler.workspaces; + +import org.junit.jupiter.api.Test; +import p.studio.compiler.models.AnalysisSnapshot; +import p.studio.compiler.models.BuildResult; +import p.studio.compiler.models.CompileResult; + +import java.lang.reflect.RecordComponent; +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.*; + +class BuilderPipelinePublicSurfaceTest { + + @Test + void publicServiceSurfaceMustExposeExplicitEntrypointsAndNoPublicRun() { + final var publicMethodNames = Arrays.stream(BuilderPipelineService.class.getDeclaredMethods()) + .filter(method -> java.lang.reflect.Modifier.isPublic(method.getModifiers())) + .map(method -> method.getName()) + .collect(Collectors.toSet()); + + assertTrue(publicMethodNames.contains("analyze"), "public surface must expose analyze"); + assertTrue(publicMethodNames.contains("compile"), "public surface must expose compile"); + assertTrue(publicMethodNames.contains("build"), "public surface must expose build"); + assertFalse(publicMethodNames.contains("run"), "public surface must not expose legacy run"); + } + + @Test + void analysisSnapshotMustExposeMinimumSharedContract() { + assertEquals( + Set.of("diagnostics", "resolvedWorkspace", "fileTable", "irBackend"), + recordComponentNames(AnalysisSnapshot.class), + "analysis snapshot must expose the minimum shared contract"); + } + + @Test + void compileResultMustExposeValidatedInMemoryArtifacts() { + final var componentNames = recordComponentNames(CompileResult.class); + + assertTrue(componentNames.contains("analysisSnapshot"), "compile result must retain analysis snapshot"); + assertTrue(componentNames.contains("diagnostics"), "compile result must expose diagnostics"); + assertTrue(componentNames.contains("bytecodeModule"), "compile result must expose bytecode module"); + assertTrue(componentNames.contains("bytecodeBytes"), "compile result must expose serialized bytecode bytes"); + } + + @Test + void buildResultMustExposeArtifactPathAndCompilePayload() { + final var componentNames = recordComponentNames(BuildResult.class); + + assertTrue(componentNames.contains("compileResult"), "build result must retain compile payload"); + assertTrue(componentNames.contains("diagnostics"), "build result must expose diagnostics"); + assertTrue(componentNames.contains("bytecodeArtifactPath"), "build result must expose artifact path"); + } + + private Set recordComponentNames(final Class type) { + assertTrue(type.isRecord(), () -> type.getSimpleName() + " must remain a record contract"); + return Arrays.stream(type.getRecordComponents()) + .map(RecordComponent::getName) + .collect(Collectors.toSet()); + } +}