From 54ba70afb8b58132fbe88b18fb68d44126b2ae3f Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Mon, 30 Mar 2026 18:54:48 +0100 Subject: [PATCH] agendas/decisions/plans for re-shape of compiler pipeline --- discussion/index.ndjson | 5 +- ...9-studio-debugger-workspace-integration.md | 127 ++++++++++++ ...tudio-code-editor-workspace-foundations.md | 178 ++++++++++++++++ ...er-analyze-compile-build-pipeline-split.md | 194 ++++++++++++++++++ ...er-analyze-compile-build-pipeline-split.md | 164 +++++++++++++++ ...-pipeline-spec-and-contract-propagation.md | 105 ++++++++++ ...ilder-pipeline-service-into-entrypoints.md | 124 +++++++++++ ...ites-and-tests-to-build-compile-analyze.md | 111 ++++++++++ 8 files changed, 1007 insertions(+), 1 deletion(-) create mode 100644 discussion/workflow/agendas/AGD-0009-studio-debugger-workspace-integration.md create mode 100644 discussion/workflow/agendas/AGD-0010-studio-code-editor-workspace-foundations.md create mode 100644 discussion/workflow/agendas/AGD-0011-compiler-analyze-compile-build-pipeline-split.md create mode 100644 discussion/workflow/decisions/DEC-0007-compiler-analyze-compile-build-pipeline-split.md create mode 100644 discussion/workflow/plans/PLN-0009-compiler-pipeline-spec-and-contract-propagation.md create mode 100644 discussion/workflow/plans/PLN-0010-refactor-builder-pipeline-service-into-entrypoints.md create mode 100644 discussion/workflow/plans/PLN-0011-migrate-callsites-and-tests-to-build-compile-analyze.md diff --git a/discussion/index.ndjson b/discussion/index.ndjson index 3cabcc2f..15ef5907 100644 --- a/discussion/index.ndjson +++ b/discussion/index.ndjson @@ -1,4 +1,4 @@ -{"type":"meta","next_id":{"DSC":9,"AGD":9,"DEC":7,"PLN":9,"LSN":25,"CLSN":1}} +{"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"}]} @@ -7,3 +7,6 @@ {"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":"review","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":"review","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":"review","created_at":"2026-03-30","updated_at":"2026-03-30","ref_decisions":["DEC-0007"]}],"lessons":[]} diff --git a/discussion/workflow/agendas/AGD-0009-studio-debugger-workspace-integration.md b/discussion/workflow/agendas/AGD-0009-studio-debugger-workspace-integration.md new file mode 100644 index 00000000..6a5a3469 --- /dev/null +++ b/discussion/workflow/agendas/AGD-0009-studio-debugger-workspace-integration.md @@ -0,0 +1,127 @@ +--- +id: AGD-0009 +ticket: studio-debugger-workspace-integration +title: Integrar ../debugger ao Studio como workspace dedicado +status: open +created: 2026-03-30 +resolved: +decision: +tags: + - studio + - debugger + - workspace + - integration + - shell +--- + +## Pain + +O shell do Studio ja anuncia `WorkspaceId.DEBUG` e exibe `Debug` na workspace rail, mas nao registra nenhum workspace concreto para esse slot. + +Hoje isso deixa o produto num estado inconsistente: + +- a shell promete um `Debugger/Profiler` como workspace baseline; +- `MainView` publica a opcao `Debug` na navegacao; +- `WorkspaceHost` exige que o workspace esteja registrado; +- a implementacao real do `Debug` continua fora do Studio, no sibling repo `../debugger`. + +Sem uma discussion canonica, a integracao tende a cair em um de tres atalhos ruins: + +- abrir o debugger como app externo e fingir que isso equivale a um workspace; +- embutir a aplicacao JavaFX existente dentro do Studio sem alinhar ciclo de vida, eventos e theming; +- reescrever tudo no Studio e perder o que o `../debugger` ja estabilizou em protocolo, controle de execucao e estado. + +## Context + +Domain owner: `studio` +Owner surface: `docs/specs/studio` +Cross-domain input: sibling repo `../debugger` + +Superficies relevantes hoje: + +- `docs/specs/studio/1. Studio Shell and Workspace Layout Specification.md` ja define `Debugger/Profiler` como parte do baseline workspace set; +- `docs/specs/studio/2. Studio UI Foundations Specification.md` exige um modelo de workspaces orientado a eventos, com bus por workspace e republishing para o bus global; +- `prometeu-studio/src/main/java/p/studio/window/MainView.java` ja inclui `WorkspaceId.DEBUG` na rail, mas o `register(...)` correspondente esta comentado; +- `prometeu-studio/src/main/java/p/studio/workspaces/Workspace.java` exige um contrato de `rootNode()`, `load()`, `unLoad()` e integra o workspace a um `StudioWorkspaceEventBus`; +- `../debugger` ja existe como aplicacao JavaFX separada, com `Application`/`Stage`, FXML, Dagger, i18n, cliente DevTools, protocolo TCP/JSONL e controle de execucao. + +O boundary de produto tambem ja aponta a direcao correta: + +- o shell do Studio deve enquadrar workspaces sem absorver detalhe operacional; +- logs e detalhe de execucao pertencem ao workspace que os possui; +- o debugger e uma superficie de execucao, nao um detalhe lateral do painel global de utilidades. + +## Open Questions + +- [ ] O objetivo da primeira integracao e hospedar a experiencia atual do `../debugger` quase inteira, ou abrir um primeiro wave menor sob o contrato nativo de workspace do Studio? +- [ ] Quais partes do `../debugger` sao `core` reaproveitavel dentro do Studio, e quais sao shell/bootstrap de app standalone que nao devem atravessar a fronteira? +- [ ] Qual deve ser a topologia de dependencia: composite build entre repositorios siblings, extracao para modulos compartilhados, ou migracao seletiva de codigo? +- [ ] Quem passa a ser o owner do ciclo de vida da sessao de debug: o `DebugWorkspace`, a shell do Studio, ou um servico compartilhado com a run surface? +- [ ] Como eventos, telemetria, logs e estados do debugger entram no bus de workspace e no bus global sem criar um segundo sistema paralelo de notificacao? +- [ ] O primeiro corte deve incluir `profiler` junto com `debugger`, ou o baseline inicial fecha apenas `debugger` e deixa profiling como extensao posterior? +- [ ] Como preservar tema, i18n e consistencia visual se parte da UI atual do `../debugger` ainda estiver em FXML e recursos proprios? +- [ ] O app standalone `../debugger` continuara existindo como consumidor paralelo do mesmo core, ou a integracao no Studio passa a ser o destino primario? + +## Options + +### Option A - Launcher externo a partir do Studio +- **Approach:** O Studio oferece um ponto de entrada para abrir `../debugger` como processo/janela externa, mantendo a integracao dentro da shell apenas como acao de lancamento. +- **Pro:** Menor custo inicial e reaproveitamento maximo da app atual. +- **Con:** Nao entrega um workspace real do Studio, fragmenta estado/sessao e conflita com a baseline shell spec. +- **Maintainability:** Fraca como arquitetura final. Pode servir no maximo como ponte temporaria, mas nao resolve o contrato de workspace. + +### Option B - Embutir a UI atual do debugger quase inteira dentro de um workspace host +- **Approach:** Reaproveitar FXML/controllers do `../debugger` e monta-los dentro de um `DebugWorkspace`, fazendo adaptacoes localizadas de DI, lifecycle e navegacao. +- **Pro:** Reaproveita mais UI existente e acelera a primeira tela funcional. +- **Con:** Carrega para dentro do Studio um bootstrap orientado a `Application`/`Stage`, com modelo proprio de lifecycle, theming e eventos que nao casa naturalmente com o contrato de workspace atual. +- **Maintainability:** Media para baixa. Economiza reescrita imediata, mas cristaliza um boundary torto entre app standalone e workspace embutido. + +### Option C - Workspace nativo do Studio apoiado em core extraido do debugger +- **Approach:** Tratar o `../debugger` como fonte de servicos, protocolo, estado e controle de execucao reaproveitaveis, mas implementar o `DebugWorkspace` como composicao nativa do Studio sobre o contrato `Workspace` + bus tipado + lifecycle-managed controls. +- **Pro:** Alinha shell spec, workspace framework e boundary de produto, sem descartar o investimento ja feito no debugger. +- **Con:** Exige separar explicitamente o que e `core` reutilizavel e o que e shell standalone, entao a primeira onda precisa de mais desenho tecnico. +- **Maintainability:** Forte. Preserva a direcao arquitetural correta e permite que Studio e app standalone compartilhem nucleo sem colapsarem num acoplamento acidental. + +### Option D - Migracao integral do debugger para dentro do Studio +- **Approach:** Absorver codigo e UI do `../debugger` para dentro dos modulos do Studio e tratar a aplicacao standalone como legado a ser aposentado. +- **Pro:** Simplifica ownership futuro se o produto decidir convergir totalmente para uma unica shell. +- **Con:** E a aposta mais cara e mais irreversivel, antes mesmo de fechar o contrato de integracao e o que ainda deve continuar independente. +- **Maintainability:** Media. Pode ser boa no longo prazo, mas e prematura enquanto o boundary entre `workspace` e `app standalone` ainda nao esta fechado. + +## Discussion + +O ponto principal nao e "como mostrar alguma tela de debug no Studio". O ponto principal e decidir qual contrato queremos estabilizar entre: + +- a shell do Studio, que ja assume workspaces independentes e orientados a eventos; +- o `DebugWorkspace`, que precisa ser um workspace real, com ownership claro de detalhe operacional; +- e o `../debugger`, que hoje concentra bootstrap de app, protocolo, estado e UI numa aplicacao separada. + +O fato de a rail ja ter `Debug` e a spec ja falar em `Debugger/Profiler` indica que a integracao nao e trabalho especulativo. +Ela ja faz parte da topologia esperada do Studio. + +Por isso, as opcoes que preservam o debugger apenas como janela externa ou que arrastam a app inteira para dentro do host sem remodelar o boundary resolvem pouco: + +- a primeira evita o trabalho agora, mas nao entrega o produto prometido pela shell; +- a segunda reaproveita UI, mas importa um modelo arquitetural que nao conversa bem com `Workspace`, `StudioWorkspaceEventBus`, theming compartilhado e lifecycle-managed controls. + +O caminho mais coerente parece ser separar o problema em duas camadas: + +1. um `debugger core` reaproveitavel, com sessao, protocolo, telemetria, logs e controle de execucao; +2. uma composicao de `DebugWorkspace` nativa do Studio, que consome esse core como mais um workspace do shell. + +Isso nao obriga uma reescrita total imediata da logica do debugger. +Obriga apenas que a UI e o bootstrap standalone parem de ser tratados como se fossem a fronteira certa de integracao. + +## Resolution + +Recommended direction: seguir com **Option C**. + +A agenda deve convergir para uma decisao com os seguintes fechamentos: + +1. `Debug` no Studio deve virar um workspace real, nao apenas launcher de app externo; +2. o boundary correto de reaproveitamento esta em servicos/protocolo/estado do debugger, nao no bootstrap `Application`/`Stage` como unidade de integracao; +3. o workspace integrado deve obedecer ao contrato do Studio para lifecycle, event bus, theming e i18n; +4. o destino do app standalone precisa ser explicitado: consumidor paralelo do mesmo core durante migracao, ou superficie secundaria apos a integracao; +5. o primeiro corte deve declarar se `profiler` entra junto com `debugger` ou fica explicitamente fatiado para depois. + +Next step suggestion: converter esta agenda em uma `decision` que feche o modelo de integracao, o boundary de ownership entre `studio` e `../debugger`, a topologia de dependencias entre repositorios e o escopo da primeira wave de `DebugWorkspace`. diff --git a/discussion/workflow/agendas/AGD-0010-studio-code-editor-workspace-foundations.md b/discussion/workflow/agendas/AGD-0010-studio-code-editor-workspace-foundations.md new file mode 100644 index 00000000..14207816 --- /dev/null +++ b/discussion/workflow/agendas/AGD-0010-studio-code-editor-workspace-foundations.md @@ -0,0 +1,178 @@ +--- +id: AGD-0010 +ticket: studio-code-editor-workspace-foundations +title: Iniciar foundations do Code Editor no Studio sem LSP +status: open +created: 2026-03-30 +resolved: +decision: +tags: + - studio + - editor + - workspace + - multi-frontend + - lsp-deferred +--- + +## Pain + +O shell do Studio ja assume `Code Editor` como parte do baseline workspace set, mas a implementacao atual do `EditorWorkspace` ainda e apenas um `CodeArea` com texto hardcoded e botoes sem modelo real de documento, tabs, arquivos, dirty state ou sessao de projeto. + +Ao mesmo tempo, queremos iniciar os trabalhos do editor agora, com foco em UI e infraestrutura robusta para varios frontends, mas sem cair em uma dependencia prematura de LSP. + +Sem fechar a boundary agora, a implementacao pode desviar para dois extremos ruins: + +- o Studio virar uma casca quase vazia que depende de cada frontend ate para abrir, salvar e manter buffers; +- ou o Studio absorver semantica demais e virar uma segunda autoridade sobre parsing, diagnosticos e modelo de compilacao. + +## Context + +Domain owner: `studio` +Owner surface: `docs/specs/studio` +Cross-domain input: `compiler` + +Superficies relevantes hoje: + +- `docs/specs/studio/1. Studio Shell and Workspace Layout Specification.md` ja define `Code Editor` como workspace baseline do shell; +- `docs/specs/studio/2. Studio UI Foundations Specification.md` exige workspaces com composicao root, event bus tipado, lifecycle-managed controls e infra reutilizavel; +- `prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorWorkspace.java` hoje monta um `CodeArea` simples sem modelo de arquivos do projeto; +- `prometeu-studio/src/main/java/p/studio/projects/ProjectLanguageCatalogService.java` ja consome `FrontendRegistryService` e `FrontendSpec`, o que mostra que o Studio ja reconhece multiplos frontends e source roots por linguagem; +- `prometeu-compiler/.../FrontendSpec.java` ja modela `languageId`, `allowedExtensions`, `sourceRoots`, `caseSensitive` e versoes de stdlib; +- o compiler hoje ainda descobre e le fontes diretamente do filesystem: `LoadSourcesPipelineStage` faz `walkFileTree(...)` nos `sourceRoots`, `BuilderPipelineContext.compilerContext(...)` instancia `SourceProviderFactory.filesystem()`, e `SourceHandle` le bytes com `Files.readAllBytes(path)`; +- `docs/roadmaps/lsp/` ja existe como trilha separada, mas esta wave quer editor sem depender de LSP; +- o precedente do packer fixa uma boa disciplina de ownership, mas ele nao deve ser copiado mecanicamente para o editor sem discutir a diferenca entre semantica de dominio e sessao generica de edicao. + +O ponto mais sensivel desta agenda e justamente essa diferenca: + +- no packer, Studio nao deve reinventar semantica de asset, snapshots operacionais ou write lanes de dominio; +- no editor, leitura/escrita de arquivos fonte, dirty tracking, buffers em memoria e snapshots documentais fazem parte da propria experiencia do workspace e nao sao, por si so, semantica de linguagem. + +Direcao adicional ja explicitada para a UX: + +- o editor deve seguir um baseline proximo ao modelo do IntelliJ; +- a ala esquerda deve ser um `Project Navigator` com arquivos/pastas relevantes do projeto; +- a area central deve ter tabs de arquivos abertos no topo e o editor rico no corpo principal; +- a regiao inferior deve ser um helper persistente para prompts, tips e feedback contextual sobre o codigo atual, funcionando mais como `advanced editor log` do que como console cru. + +## Open Questions + +- [ ] Qual e o seam normativo para ligar `document snapshots` do editor ao compiler: substituir `SourceProviderFactory.filesystem()` por provider de sessao, ou introduzir uma etapa explicita que materializa uma visao congelada de documentos antes do pipeline? +- [ ] O primeiro wave do editor deve nascer com tabs multiplas e sessao multi-documento completa, ou tabs multiplas com uma politica mais simples de documentos ativos/carregados? +- [ ] Como o `EditorWorkspace` descobre quais arquivos e source roots sao editaveis a partir de `ProjectReference.languageId` e `FrontendSpec`? +- [ ] Quem detecta modificacoes externas em arquivos abertos e como o conflito entre disco e buffer em memoria deve aparecer para o usuario? +- [ ] Alem do baseline ja aceito (`Project Navigator`, tabs, editor central, helper inferior), a primeira wave tambem deve incluir `outline` ou `status bar`, ou esses elementos ficam explicitamente para depois? +- [ ] Como preservar uma UI consistente entre linguagens diferentes sem forcar cada frontend a carregar seu proprio mini-editor completo? +- [ ] O que fica explicitamente fora desta wave por ausencia de LSP: autocomplete, go to definition, semantic diagnostics ao digitar, symbols, rename, code actions? + +## Options + +### Option A - Studio como casca pura; frontend/backends fazem o resto +- **Approach:** O Studio hospeda a area visual do editor, mas leitura, escrita, buffers, snapshots e demais operacoes relevantes ficam delegadas a adaptadores por linguagem ou a servicos externos. +- **Pro:** Mantem o Studio "leve" e minimiza responsabilidade local. +- **Con:** Duplica infraestrutura generica em cada frontend, acopla UX basica a backend de linguagem e torna dificil sustentar uma experiencia coerente multi-FE sem LSP. +- **Maintainability:** Fraca. A boundary fica formalmente limpa, mas o custo reaparece como fragmentacao de sessao, inconsistencias de UX e adaptadores repetidos. + +### Option B - Studio possui sessao generica de documentos; frontends possuem semantica +- **Approach:** O Studio passa a possuir uma camada generica de editor para descoberta de arquivos, open/save, dirty tracking, tabs, estado ativo, deteccao de mudanca externa e snapshots imutaveis de documento em memoria; frontends consomem essa camada como entrada para highlighting, parsing, diagnosticos e outras features atuais ou futuras. +- **Pro:** Cria uma base robusta para varios frontends mesmo sem LSP, evita duplicacao de infra generica e mantem a semantica de linguagem fora do workspace visual. +- **Con:** Exige disciplina para nao confundir `snapshot documental` com `snapshot semantico` do compiler e para nao deixar a camada generica vazar regras de linguagem. +- **Maintainability:** Forte. A separacao entre sessao de edicao e semantica de linguagem fica clara e expansivel. + +### Option C - Cada frontend possui seu proprio stack de editor end-to-end +- **Approach:** O Studio oferece apenas um host de workspace, e cada frontend implementa seu proprio editor, file model, snapshots e event wiring do zero. +- **Pro:** Maxima liberdade por linguagem. +- **Con:** Destrói a chance de um framework comum de editor, duplica problema de tabs/buffers/save/conflicts e torna a shell dependente de N mini-produtos locais. +- **Maintainability:** Fraca. Funciona para prototipos isolados, mas nao para um Studio que quer suportar varios FEs sob uma UX comum. + +### Option D - Esperar LSP e desenhar o editor em torno dele +- **Approach:** Adiar a infra editorial mais seria ate que exista um backend LSP suficientemente funcional e modelar o editor a partir desse contrato. +- **Pro:** Pode reduzir retrabalho se o LSP for a unica fronteira desejada. +- **Con:** Conflita com o objetivo desta wave, atrasa o editor, e ainda nao resolve ownership de file IO, buffers e dirty state, que continuam existindo mesmo com LSP. +- **Maintainability:** Media para baixa. O LSP ajuda na semantica, mas nao substitui a sessao generica de edicao. + +## Discussion + +O precedente do packer e util, mas ele nao responde sozinho a pergunta desta agenda. + +No packer, a semantica de dominio e forte: + +- identidade de asset; +- validacao; +- write lane; +- snapshots operacionais; +- causality de eventos. + +Nessa area, faz sentido Studio atuar mais como adaptador editorial do que como autoridade. + +No editor de codigo, porem, existe uma camada anterior a qualquer semantica de linguagem: + +- abrir arquivo; +- manter buffer em memoria; +- controlar dirty state; +- salvar em disco; +- alternar tabs; +- versionar snapshots documentais; +- reagir a mudancas externas; +- expor um modelo de sessao que qualquer FE consiga consumir. + +Essas responsabilidades nao sao "semantica de compiler". Sao responsabilidades normais de um editor. +Se o Studio se recusar a possui-las, cada frontend ou integracao futura precisara reinventar a mesma infraestrutura. + +Do ponto de vista de UX, a direcao mais solida e assumir um baseline de tres regioes dentro do `EditorWorkspace`: + +1. `Project Navigator` na esquerda +2. `Editor Workarea` no centro, com tabs acima e editor no corpo +3. `Editor Helper Panel` na base, para tips, prompts, hints e feedback contextual + +Esse painel inferior merece cuidado de nomenclatura e ownership. +Ele nao deve nascer como "console generico" nem como dumping ground de logs tecnicos. +Melhor trata-lo como uma superficie editorial guiada pelo contexto do documento ativo. + +Sugestao de papel para esse helper: + +- mostrar hints sobre arquivo, linguagem e estado do documento; +- receber mensagens de parse/local validation quando existirem; +- explicar bloqueios de save, conflitos de disco e prompts do editor; +- no futuro, acomodar saidas de LSP ou FE sem acoplar a shell global a isso. + +Em outras palavras: ele deve ser um `assistant/log` de workspace, nao um substituto do painel global `Activity` e nao um terminal cru. + +O boundary mais saudavel parece ser: + +1. o Studio possui a sessao generica de documentos e a UX editorial comum; +2. os frontends recebem snapshots documentais imutaveis como entrada; +3. parsing, name resolution, diagnostics, semantic tokens, completions e afins continuam fora da camada generica do editor; +4. LSP, quando existir, entra como um consumidor/provedor de semantica sobre essa base, nao como substituto da base. + +O estado atual do compiler reforca essa necessidade. +Hoje o build pipeline ainda assume filesystem como source of truth imediata: + +- os arquivos sao descobertos por crawl direto nos `sourceRoots`; +- o `BuilderPipelineContext` nasce com `SourceProviderFactory.filesystem()`; +- cada `SourceHandle` le bytes do `Path` canonico. + +Isso significa que, se quisermos uniformizar Studio, FE services e LSP futuro em torno de uma mesma visao documental, precisamos introduzir explicitamente uma camada de `document snapshot` antes do consumo pelo pipeline. +O lado bom e que ja existe um seam util: `SourceProviderFactory` nao esta hardcoded em todos os callsites e ja sugere providers alternativos, inclusive `in-memory`. + +Isso tambem ajuda com a meta de varios FEs: + +- `FrontendSpec` ja informa roots e extensoes; +- o `EditorWorkspace` pode montar a superficie a partir disso; +- e cada linguagem fica livre para plugar servicos sem destruir o modelo editorial comum. + +## Resolution + +Recommended direction: seguir com **Option B**. + +A agenda deve convergir para uma decisao com os seguintes fechamentos: + +1. o Studio deve possuir uma camada generica de `document/session` para o Code Editor; +2. essa camada pode ler e escrever arquivos fonte e manter snapshots documentais em memoria; +3. essa camada nao deve possuir semantica de linguagem, parsing autoritativo ou diagnosticos como responsabilidade primaria; +4. frontends devem consumir snapshots documentais do editor por um contrato explicito, imutavel e versionado; +5. como o compiler hoje ainda le do filesystem, a decisao precisa fechar uma etapa/seam concreta para injetar `document snapshots` antes do pipeline, uniformizando a entrada de Studio, FE services e LSP futuro; +6. LSP fica explicitamente fora do primeiro wave, mas a modelagem precisa deixar caminho limpo para ele; +7. a primeira wave do editor deve normatizar explicitamente o baseline visual do workspace: `Project Navigator` na esquerda, tabs no topo da area central, editor rico no corpo e `Editor Helper Panel` inferior reservado; +8. o `Editor Helper Panel` nasce passivo na primeira wave, como espaco reservado para prompts, tips e feedback contextual, sem obrigar interatividade imediata. + +Next step suggestion: converter esta agenda em uma `decision` que feche o boundary entre `EditorWorkspace`, sessao documental do Studio e servicos de frontend, incluindo o escopo exato da primeira wave de UI sem LSP. 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 new file mode 100644 index 00000000..a01423b6 --- /dev/null +++ b/discussion/workflow/agendas/AGD-0011-compiler-analyze-compile-build-pipeline-split.md @@ -0,0 +1,194 @@ +--- +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 new file mode 100644 index 00000000..665b0a03 --- /dev/null +++ b/discussion/workflow/decisions/DEC-0007-compiler-analyze-compile-build-pipeline-split.md @@ -0,0 +1,164 @@ +--- +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 new file mode 100644 index 00000000..d68be1cf --- /dev/null +++ b/discussion/workflow/plans/PLN-0009-compiler-pipeline-spec-and-contract-propagation.md @@ -0,0 +1,105 @@ +--- +id: PLN-0009 +ticket: compiler-analyze-compile-build-pipeline-split +title: Propagate DEC-0007 into compiler pipeline specs and public contracts +status: review +created: 2026-03-30 +completed: +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 new file mode 100644 index 00000000..01b71475 --- /dev/null +++ b/discussion/workflow/plans/PLN-0010-refactor-builder-pipeline-service-into-entrypoints.md @@ -0,0 +1,124 @@ +--- +id: PLN-0010 +ticket: compiler-analyze-compile-build-pipeline-split +title: Refactor BuilderPipelineService into explicit analyze, compile, and build entrypoints +status: review +created: 2026-03-30 +completed: +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 new file mode 100644 index 00000000..88390fe3 --- /dev/null +++ b/discussion/workflow/plans/PLN-0011-migrate-callsites-and-tests-to-build-compile-analyze.md @@ -0,0 +1,111 @@ +--- +id: PLN-0011 +ticket: compiler-analyze-compile-build-pipeline-split +title: Migrate compiler callsites and tests to explicit build, compile, and analyze entrypoints +status: review +created: 2026-03-30 +completed: +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.