dev/multi-frontend-serializable-ir #18
@ -1,4 +1,4 @@
|
||||
{"type":"meta","next_id":{"DSC":66,"AGD":69,"DEC":45,"PLN":124,"LSN":60,"CLSN":1}}
|
||||
{"type":"meta","next_id":{"DSC":66,"AGD":69,"DEC":45,"PLN":124,"LSN":61,"CLSN":1}}
|
||||
{"type":"discussion","id":"DSC-0065","status":"open","ticket":"multi-frontend-avoid-premature-abstractions","title":"Evitar abstracoes prematuras na preparacao multi-frontend","created_at":"2026-07-15","updated_at":"2026-07-15","tags":["compiler","compiler-general","studio","frontend","architecture","multi-frontend","simplicity"],"agendas":[{"id":"AGD-0068","file":"AGD-0068-multi-frontend-avoid-premature-abstractions.md","status":"open","created_at":"2026-07-15","updated_at":"2026-07-15"}],"decisions":[],"plans":[],"lessons":[]}
|
||||
{"type":"discussion","id":"DSC-0064","status":"open","ticket":"multi-frontend-architectural-tests","title":"Testes arquiteturais para fronteiras multi-frontend","created_at":"2026-07-15","updated_at":"2026-07-15","tags":["compiler","compiler-general","studio","frontend","architecture","tests","multi-frontend"],"agendas":[{"id":"AGD-0067","file":"AGD-0067-multi-frontend-architectural-tests.md","status":"open","created_at":"2026-07-15","updated_at":"2026-07-15"}],"decisions":[],"plans":[],"lessons":[]}
|
||||
{"type":"discussion","id":"DSC-0063","status":"open","ticket":"multi-frontend-synthetic-test-frontend","title":"Frontend sintetico de teste para provar neutralidade do pipeline","created_at":"2026-07-15","updated_at":"2026-07-15","tags":["compiler","compiler-general","frontend","tests","backend","multi-frontend"],"agendas":[{"id":"AGD-0066","file":"AGD-0066-multi-frontend-synthetic-test-frontend.md","status":"open","created_at":"2026-07-15","updated_at":"2026-07-15"}],"decisions":[],"plans":[],"lessons":[]}
|
||||
@ -6,7 +6,7 @@
|
||||
{"type":"discussion","id":"DSC-0061","status":"open","ticket":"multi-frontend-sdk-canonical-definition","title":"Auditoria e centralizacao gradual da definicao canonica do SDK","created_at":"2026-07-15","updated_at":"2026-07-15","tags":["compiler","compiler-general","sdk","stdlib","hostcalls","intrinsics","multi-frontend"],"agendas":[{"id":"AGD-0064","file":"AGD-0064-multi-frontend-sdk-canonical-definition.md","status":"open","created_at":"2026-07-15","updated_at":"2026-07-15"}],"decisions":[],"plans":[],"lessons":[]}
|
||||
{"type":"discussion","id":"DSC-0060","status":"open","ticket":"multi-frontend-validation-boundaries","title":"Separar validacoes de linguagem e validacoes de plataforma","created_at":"2026-07-15","updated_at":"2026-07-15","tags":["compiler","compiler-general","compiler-pbs","backend","validation","multi-frontend"],"agendas":[{"id":"AGD-0063","file":"AGD-0063-multi-frontend-validation-boundaries.md","status":"open","created_at":"2026-07-15","updated_at":"2026-07-15"}],"decisions":[],"plans":[],"lessons":[]}
|
||||
{"type":"discussion","id":"DSC-0059","status":"open","ticket":"multi-frontend-common-lifecycle","title":"Extrair lifecycle comum das responsabilidades do frontend PBS","created_at":"2026-07-15","updated_at":"2026-07-15","tags":["compiler","compiler-general","compiler-pbs","lifecycle","backend","multi-frontend"],"agendas":[{"id":"AGD-0062","file":"AGD-0062-multi-frontend-common-lifecycle.md","status":"open","created_at":"2026-07-15","updated_at":"2026-07-15"}],"decisions":[],"plans":[],"lessons":[]}
|
||||
{"type":"discussion","id":"DSC-0058","status":"in_progress","ticket":"multi-frontend-serializable-ir","title":"Manter a IR comum serializavel por design","created_at":"2026-07-15","updated_at":"2026-07-15","tags":["compiler","compiler-general","ir","backend","serialization","multi-frontend"],"agendas":[{"id":"AGD-0061","file":"AGD-0061-multi-frontend-serializable-ir.md","status":"accepted","created_at":"2026-07-15","updated_at":"2026-07-15"}],"decisions":[{"id":"DEC-0044","file":"DEC-0044-serializable-common-ir-boundary.md","status":"accepted","created_at":"2026-07-15","updated_at":"2026-07-15","ref_agenda":"AGD-0061"}],"plans":[{"id":"PLN-0119","file":"PLN-0119-document-irbackend-serializability-invariants.md","status":"done","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0044"]},{"id":"PLN-0120","file":"PLN-0120-audit-public-irbackend-contract-shape.md","status":"done","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0044"]},{"id":"PLN-0121","file":"PLN-0121-add-serializable-irbackend-reflection-guardrails.md","status":"done","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0044"]},{"id":"PLN-0122","file":"PLN-0122-prove-deterministic-irbackend-ordering.md","status":"done","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0044"]},{"id":"PLN-0123","file":"PLN-0123-fix-concrete-irbackend-serialization-leaks.md","status":"done","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0044"]}],"lessons":[]}
|
||||
{"type":"discussion","id":"DSC-0058","status":"done","ticket":"multi-frontend-serializable-ir","title":"Manter a IR comum serializavel por design","created_at":"2026-07-15","updated_at":"2026-07-15","tags":["compiler","compiler-general","ir","backend","serialization","multi-frontend"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0060","file":"discussion/lessons/DSC-0058-multi-frontend-serializable-ir/LSN-0060-data-contract-first-for-serializable-irbackend.md","status":"done","created_at":"2026-07-15","updated_at":"2026-07-15"}]}
|
||||
{"type":"discussion","id":"DSC-0057","status":"done","ticket":"multi-frontend-frontend-backend-contract","title":"Estabilizar contrato entre frontend e backend comum","created_at":"2026-07-15","updated_at":"2026-07-15","tags":["compiler","compiler-general","compiler-pbs","ir","backend","multi-frontend"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0059","file":"discussion/lessons/DSC-0057-multi-frontend-frontend-backend-contract/LSN-0059-common-irbackend-handoff-and-backend-guardrails.md","status":"done","created_at":"2026-07-15","updated_at":"2026-07-15"}]}
|
||||
{"type":"discussion","id":"DSC-0056","status":"done","ticket":"multi-frontend-remove-pbs-branches","title":"Generalizar o contrato LSP/editorial para frontends","created_at":"2026-07-15","updated_at":"2026-07-15","tags":["compiler","compiler-general","compiler-pbs","studio","frontend","coupling","multi-frontend"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0058","file":"discussion/lessons/DSC-0056-multi-frontend-remove-pbs-branches/LSN-0058-generic-frontend-editorial-contract-for-lsp.md","status":"done","created_at":"2026-07-15","updated_at":"2026-07-15"}]}
|
||||
{"type":"discussion","id":"DSC-0055","status":"done","ticket":"multi-frontend-compiler-vs-language-services","title":"Separar compilacao de servicos editoriais de frontend","created_at":"2026-07-15","updated_at":"2026-07-15","tags":["compiler","compiler-general","studio","lsp","editor","frontend","multi-frontend"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0056","file":"discussion/lessons/DSC-0055-multi-frontend-compiler-vs-language-services/LSN-0056-compile-first-frontends-with-optional-editorial-capabilities.md","status":"done","created_at":"2026-07-15","updated_at":"2026-07-15"}]}
|
||||
|
||||
@ -0,0 +1,82 @@
|
||||
---
|
||||
id: LSN-0060
|
||||
ticket: multi-frontend-serializable-ir
|
||||
title: Data contract first for serializable IRBackend
|
||||
created: 2026-07-15
|
||||
tags: [compiler, compiler-general, ir, backend, serialization, multi-frontend]
|
||||
---
|
||||
|
||||
# Data contract first for serializable IRBackend
|
||||
|
||||
## Original Problem
|
||||
|
||||
The compiler already had a common executable handoff: `IRBackend`. PBS emits it, and common backend stages consume it before lowering to `IRVM`.
|
||||
|
||||
The remaining risk was subtler than direct PBS coupling. A Java-only handoff can accidentally grow around process-local assumptions: callbacks, services, object identity, mutable global state, unordered collections, lazy values, or direct references between live objects. Those shapes can work inside one JVM and still make a future external frontend or out-of-process boundary expensive to add.
|
||||
|
||||
The work needed to keep the handoff serializable by design without choosing JSON, Protobuf, RPC, plugin loading, or a separate process too early.
|
||||
|
||||
## Consolidated Decision
|
||||
|
||||
`IRBackend` is a data contract first.
|
||||
|
||||
Public `IRBackend` contract types must remain modelable as an acyclic, deterministic data graph made from primitives, strings, enums, immutable values, ordered lists, explicit ids, stable symbolic keys, and source attribution values such as file ids and spans.
|
||||
|
||||
The public handoff must not expose callbacks, lambdas, service objects, registries, visitors, live compiler services, frontend AST/parser/token/semantic/editorial objects, mutable global state, object identity semantics, unordered output-affecting collections, cyclic public references, process-dependent lazy values, or a selected wire format.
|
||||
|
||||
The important boundary is the data shape, not a codec. A future serializer should be able to consume the handoff because the public model is already disciplined, but this decision does not require a serializer to exist now.
|
||||
|
||||
## Final Implementation
|
||||
|
||||
The implementation updated the compiler-general backend spec with a new `IRBackend` serializability-by-design subsection. The spec now states the allowed and forbidden public shapes and keeps wire format selection explicitly deferred.
|
||||
|
||||
The conformance matrix added `G20-4.2.x` rows for the new requirements:
|
||||
|
||||
- public `IRBackend` modelability as an acyclic deterministic data graph;
|
||||
- rejection of callbacks, services, mutable or unordered collections, frontend-owned objects, process-dependent lazy values, cyclic public references, and wire-format commitments;
|
||||
- use of explicit ids or stable symbolic keys for cross-object references.
|
||||
|
||||
The executable guardrails live in `IRBackendExecutableContractTest`:
|
||||
|
||||
- the public contract audit covers all current `p.studio.compiler.models` handoff types and nested value types;
|
||||
- support types such as `FileId`, `ModuleId`, `CallableId`, `IntrinsicId`, `Span`, table reference records, and `ReadOnlyList` are explicitly classified;
|
||||
- reflection checks inspect public fields, record components, public constructors, public methods, and generic type arguments;
|
||||
- guardrails reject PBS/frontend exposure, callback shapes, service-like public shapes, mutable/unordered collection contracts, and other non-serializable public exposures;
|
||||
- deterministic aggregation tests prove stable ordering for functions, synthetic functions, globals, executable functions, module pools, callable signatures, intrinsic pools, reserved metadata, and required capabilities;
|
||||
- known references are locked to explicit ids or stable keys rather than direct object references.
|
||||
|
||||
The audit found no concrete public serialization leak that required changing the production model. That result is meaningful: the current `IRBackend` shape was already close to the target, so the correct implementation was spec clarification plus tests, not a redesign.
|
||||
|
||||
## Examples
|
||||
|
||||
Good public handoff shapes:
|
||||
|
||||
- `ModuleId`, `CallableId`, `IntrinsicId`, and `FileId` for table-scoped references;
|
||||
- `ReadOnlyList<T>` for ordered collections;
|
||||
- `ModuleReference`, `CallableSignatureRef`, and `IntrinsicReference` as stable table values;
|
||||
- `Span` for source attribution;
|
||||
- enums and records for fixed value surfaces.
|
||||
|
||||
Bad public handoff shapes:
|
||||
|
||||
- `Map`, `Set`, or mutable collection interfaces where output order matters;
|
||||
- `Runnable`, `Callable`, `Function`, visitors, or callbacks;
|
||||
- compiler services or registries exposed as public fields or constructor parameters;
|
||||
- frontend AST, parser, token, semantic, or editor types;
|
||||
- direct references to another handoff object where an id or ordered table entry is the stable contract.
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- Do not confuse "serializable by design" with "serialize it now." A codec is a future implementation detail.
|
||||
- Do not add typed ids everywhere by taste. Add them when a real public field would otherwise depend on textual identity, object identity, or direct object references.
|
||||
- Do not treat `ReadOnlyList` as cosmetic. Ordered collections are part of the deterministic contract.
|
||||
- Do not let a private assembler or aggregator implementation shape leak into public handoff semantics.
|
||||
- Do not move the rule into PBS specs. PBS owns how it populates the handoff; compiler-general owns the common handoff contract.
|
||||
|
||||
## References
|
||||
|
||||
- `docs/specs/compiler/20. IRBackend to IRVM Lowering Specification.md`
|
||||
- `docs/specs/compiler/22. Backend Spec-to-Test Conformance Matrix.md`
|
||||
- `prometeu-compiler/prometeu-frontend-api/src/test/java/p/studio/compiler/models/IRBackendExecutableContractTest.java`
|
||||
- `prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/specs/BackendConformanceMatrixSpecTest.java`
|
||||
- `prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/backend/irvm/LowerToIRVMServiceTest.java`
|
||||
@ -1,76 +0,0 @@
|
||||
---
|
||||
id: AGD-0061
|
||||
ticket: multi-frontend-serializable-ir
|
||||
title: Manter a IR comum serializavel por design
|
||||
status: accepted
|
||||
created: 2026-07-15
|
||||
resolved:
|
||||
decision:
|
||||
tags: [compiler, compiler-general, ir, backend, serialization, multi-frontend]
|
||||
---
|
||||
|
||||
# Agenda - Manter a IR serializavel por design
|
||||
|
||||
## Objetivo
|
||||
|
||||
Domain owner: `compiler/general`.
|
||||
|
||||
Avaliar se a IR comum pode atravessar futuramente uma fronteira de processo sem redesenho, evitando callbacks, estado global, ciclos e identity equality como parte do contrato.
|
||||
|
||||
## Contexto atual
|
||||
|
||||
O pipeline atual roda na JVM, mas frontends futuros podem ser externos. O alinhamento proibe escolher JSON, Protobuf, RPC ou processo externo agora; a discussao deve focar no formato dos dados.
|
||||
|
||||
## Escopo
|
||||
|
||||
- Auditar records/classes da IR comum.
|
||||
- Identificar referencias a servicos, objetos mutaveis, ciclos e IDs implicitos.
|
||||
- Definir principios de modelagem: IDs explicitos, listas ordenadas, enums e valores primitivos.
|
||||
|
||||
## Fora de escopo
|
||||
|
||||
- Implementar codec.
|
||||
- Serializar a saida do PBS dentro do mesmo processo.
|
||||
- Escolher wire format.
|
||||
|
||||
## Arquivos e componentes a inspecionar
|
||||
|
||||
- `prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/models/...`
|
||||
- `prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/backend/...`
|
||||
- testes `IRBackendExecutableContractTest` e `LowerToIRVMServiceTest`
|
||||
- docs de specs do compiler geral
|
||||
|
||||
## Alteracoes propostas
|
||||
|
||||
Opcao A: documentar invariantes de serializabilidade e corrigir apenas vazamentos claros.
|
||||
|
||||
Opcao B: criar tipos de ID e spans onde hoje houver identidade textual ou referencias diretas instaveis.
|
||||
|
||||
Recomendacao inicial: comecar por auditoria e testes de reflexao leves antes de qualquer migracao estrutural.
|
||||
|
||||
## Estrategia de implementacao
|
||||
|
||||
Gerar uma lista de tipos publicos da IR, revisar construtores e campos, e propor correcoes incrementais para pontos que impediriam um codec futuro.
|
||||
|
||||
## Testes necessarios
|
||||
|
||||
- Teste de reflexao sobre campos publicos/record components da IR.
|
||||
- Teste de determinismo de ordenacao.
|
||||
- Teste de ausencia de referencias a AST, servicos ou callbacks.
|
||||
|
||||
## Criterios de aceitacao
|
||||
|
||||
- A IR pode ser descrita como grafo de dados aciclico ou com referencias por ID.
|
||||
- Nenhuma escolha prematura de wire format e introduzida.
|
||||
|
||||
## Riscos
|
||||
|
||||
- Overengineering de IDs onde o contrato ainda nao exige.
|
||||
- Quebrar ergonomia de testes ao tornar todos os objetos verbosos.
|
||||
|
||||
## Decisoes que devem ser registradas
|
||||
|
||||
- Regras minimas de serializabilidade.
|
||||
- Tipos de ID que devem existir agora.
|
||||
- Itens explicitamente adiados para codec futuro.
|
||||
|
||||
@ -1,82 +0,0 @@
|
||||
---
|
||||
id: DEC-0044
|
||||
ticket: multi-frontend-serializable-ir
|
||||
title: Serializable common IR boundary
|
||||
status: accepted
|
||||
created: 2026-07-15
|
||||
ref_agenda: AGD-0061
|
||||
tags: [compiler, compiler-general, ir, backend, serialization, multi-frontend]
|
||||
---
|
||||
|
||||
## Context
|
||||
|
||||
`IRBackend` is already the common executable handoff between language frontends and common backend stages. Recent multi-frontend work locked the rule that PBS owns PBS-to-`IRBackend` lowering, while compiler-general specs own `IRBackend -> IRVM` lowering.
|
||||
|
||||
The next risk is not current PBS coupling. The risk is allowing the common handoff to grow around JVM object identity, callbacks, service references, mutable global state, implicit ordering, or cyclic object graphs. Any of those choices would make a future external frontend or out-of-process compiler boundary require a disruptive redesign.
|
||||
|
||||
This decision intentionally does not choose JSON, Protobuf, RPC, process isolation, plugin loading, or any concrete wire format. It defines only the data-shape discipline that keeps a future codec possible.
|
||||
|
||||
## Decision
|
||||
|
||||
The common `IRBackend` handoff MUST remain serializable by design.
|
||||
|
||||
For this discussion, "serializable by design" means that public `IRBackend` contract types MUST be modelable as an acyclic, deterministic data graph made of:
|
||||
|
||||
1. primitive values and strings;
|
||||
2. enums;
|
||||
3. immutable value objects;
|
||||
4. ordered lists;
|
||||
5. nullable or optional scalar fields only where absence is part of the contract;
|
||||
6. explicit identifier values for cross-references;
|
||||
7. and source attribution values such as file ids and spans.
|
||||
|
||||
The common `IRBackend` handoff MUST NOT expose, require, or rely on:
|
||||
|
||||
1. callbacks, lambdas, service objects, registries, visitors, or live compiler services;
|
||||
2. frontend AST, parser, token, semantic, or editorial objects;
|
||||
3. mutable global state as part of interpretation;
|
||||
4. object identity equality as a semantic key;
|
||||
5. unordered collections where iteration order affects output;
|
||||
6. cyclic references between public handoff objects;
|
||||
7. lazy values whose result depends on current process state;
|
||||
8. or a selected wire format.
|
||||
|
||||
Cross-object references MUST use explicit ids or stable symbolic keys. Existing identifier wrappers such as `FileId`, `ModuleId`, `CallableId`, and `IntrinsicId` are acceptable when their meaning is table-scoped and deterministic. New typed ids SHOULD be introduced only when a concrete public handoff field otherwise depends on textual identity, object identity, or a direct object reference.
|
||||
|
||||
Ordered collections MUST preserve deterministic order. Any map-like data that becomes part of the handoff MUST either be represented as an ordered list of entries or define deterministic key ordering before it reaches the public contract.
|
||||
|
||||
The initial implementation MUST be an audit-and-guardrail pass, not a codec implementation. It MUST document the invariants, add lightweight tests that detect obvious violations, and correct concrete leaks only when the current public contract already exposes a non-serializable shape.
|
||||
|
||||
## Rationale
|
||||
|
||||
This keeps the multi-frontend preparation narrow. A future external frontend needs a stable data contract before it needs a transport. Locking the data-shape discipline now prevents accidental coupling while avoiding premature infrastructure.
|
||||
|
||||
The current Java model already trends toward records, enums, ids, spans, and ordered lists. Requiring immediate structural migration everywhere would create churn before a real codec exists. Requiring auditability and guardrails gives the project a useful boundary now and leaves more invasive ID work for places where a leak is proven.
|
||||
|
||||
Object identity, service references, callbacks, and unordered iteration are especially harmful because they can work inside one JVM process while silently becoming undefined at a serialization boundary. Making those patterns forbidden in the public handoff keeps backend behavior reviewable and testable.
|
||||
|
||||
## Implications
|
||||
|
||||
Specs must describe `IRBackend` as a language-neutral data contract, not as a live object graph. Compiler-general specs must own these invariants because they apply to all frontends. PBS specs may mention how PBS populates the handoff, but they must not define serialization rules for the common contract.
|
||||
|
||||
The code implementation must start by auditing public `IRBackend` model types under `prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/models`. The first guardrail should be reflection-based and focused on public fields, record components, constructors, and public methods of the handoff types.
|
||||
|
||||
Tests should check for forbidden frontend package exposure, forbidden service/callback shapes, public unordered collection exposure, and deterministic list ordering where aggregation or lowering depends on order. Existing tests such as `IRBackendExecutableContractTest` can be extended if that keeps the guardrail local and readable.
|
||||
|
||||
The implementation must not introduce a serializer, schema language, protocol, external process, or plugin runtime as part of this decision. Those remain future decisions.
|
||||
|
||||
## Propagation Targets
|
||||
|
||||
- specs: update `docs/specs/compiler/20. IRBackend to IRVM Lowering Specification.md` with a common `IRBackend` serializability-by-design subsection; reference from `docs/specs/compiler/22. Backend Spec-to-Test Conformance Matrix.md` if conformance rows are added.
|
||||
- plans: create one implementation plan covering spec update, public-contract audit, guardrail tests, and any concrete leak fixes discovered by the audit.
|
||||
- code: inspect `prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/models/...` first; inspect backend consumers only where a public handoff field or ordering rule requires confirmation.
|
||||
- tests: extend or add tests near `IRBackendExecutableContractTest`; include deterministic ordering checks and public-contract reflection checks for non-serializable exposure.
|
||||
- docs: future lessons should teach the boundary as "data contract first, codec later" after implementation is complete.
|
||||
|
||||
## References
|
||||
|
||||
- Agenda: AGD-0061
|
||||
- Prior lesson: `discussion/lessons/DSC-0057-multi-frontend-frontend-backend-contract/LSN-0059-common-irbackend-handoff-and-backend-guardrails.md`
|
||||
- Spec: `docs/specs/compiler/20. IRBackend to IRVM Lowering Specification.md`
|
||||
- Spec: `docs/specs/compiler-languages/pbs/13. Lowering IRBackend Specification.md`
|
||||
- Test: `prometeu-compiler/prometeu-frontend-api/src/test/java/p/studio/compiler/models/IRBackendExecutableContractTest.java`
|
||||
@ -1,67 +0,0 @@
|
||||
---
|
||||
id: PLN-0119
|
||||
ticket: multi-frontend-serializable-ir
|
||||
title: Document IRBackend serializability invariants
|
||||
status: done
|
||||
created: 2026-07-15
|
||||
ref_decisions: [DEC-0044]
|
||||
tags: [compiler, compiler-general, ir, backend, serialization, multi-frontend]
|
||||
---
|
||||
|
||||
## Briefing
|
||||
|
||||
`DEC-0044` locks the common `IRBackend` handoff as a serializable-by-design data contract. The first implementation step is to make that rule visible in compiler-general specs before changing code or tests.
|
||||
|
||||
## Objective
|
||||
|
||||
Document the serializability invariants for the common `IRBackend` handoff in the compiler-general backend specification, and connect those invariants to the conformance matrix when a test row is useful.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Accepted decision: `DEC-0044`.
|
||||
- Existing common backend spec: `docs/specs/compiler/20. IRBackend to IRVM Lowering Specification.md`.
|
||||
- Existing conformance matrix: `docs/specs/compiler/22. Backend Spec-to-Test Conformance Matrix.md`.
|
||||
|
||||
## Scope
|
||||
|
||||
1. Add a compiler-general subsection defining `IRBackend` as a serializable-by-design data contract.
|
||||
2. State the allowed public contract shapes: primitives, strings, enums, immutable values, ordered lists, explicit ids, and source attribution values.
|
||||
3. State the forbidden public contract shapes: callbacks, service objects, frontend AST/parser/token/semantic/editorial objects, mutable global state, object-identity semantics, unordered contract collections, cyclic public references, lazy process-dependent values, and selected wire formats.
|
||||
4. Define the relationship between table-scoped ids such as `FileId`, `ModuleId`, `CallableId`, and `IntrinsicId` and future codec eligibility.
|
||||
5. Add conformance matrix rows only for invariants that have direct test coverage in the follow-up plans.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Do not choose JSON, Protobuf, RPC, process isolation, plugin loading, or any concrete wire format.
|
||||
- Do not define a schema language.
|
||||
- Do not change Java model code in this plan.
|
||||
- Do not move PBS-specific lowering rules into compiler-general specs.
|
||||
|
||||
## Execution Method
|
||||
|
||||
1. Update `docs/specs/compiler/20. IRBackend to IRVM Lowering Specification.md`.
|
||||
- Add the serializability subsection near the existing common `IRBackend` contract section.
|
||||
- Use normative `MUST`, `MUST NOT`, and `SHOULD` language matching `DEC-0044`.
|
||||
- Keep the wording data-shape focused, not transport focused.
|
||||
2. Update `docs/specs/compiler/22. Backend Spec-to-Test Conformance Matrix.md`.
|
||||
- Add rows for public-contract serializability guardrails only if the row can name or anticipate concrete tests from `PLN-0121` and `PLN-0122`.
|
||||
- Keep rows under compiler-general/backend ownership.
|
||||
3. Check that PBS lowering spec remains scoped to populating the handoff.
|
||||
- If references are needed, link to the compiler-general spec rather than restating the full rule.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. The compiler-general spec states that public `IRBackend` contract types are serializable by design.
|
||||
2. The spec explicitly forbids callbacks, services, frontend-owned objects, mutable global state, identity-based semantics, unordered output-affecting collections, cycles, process-dependent lazy values, and wire-format selection.
|
||||
3. The spec preserves `DEC-0044`'s deferral of codecs and external process design.
|
||||
4. Any conformance matrix changes map to concrete tests planned in `PLN-0121` or `PLN-0122`.
|
||||
|
||||
## Tests
|
||||
|
||||
Run documentation validation available in the repository, if any. At minimum, run `discussion validate` after the plan's implementation and manually inspect the changed spec section for normative consistency with `DEC-0044`.
|
||||
|
||||
## Affected Artifacts
|
||||
|
||||
- `docs/specs/compiler/20. IRBackend to IRVM Lowering Specification.md`
|
||||
- `docs/specs/compiler/22. Backend Spec-to-Test Conformance Matrix.md`
|
||||
- Optional reference touch only: `docs/specs/compiler-languages/pbs/13. Lowering IRBackend Specification.md`
|
||||
@ -1,71 +0,0 @@
|
||||
---
|
||||
id: PLN-0120
|
||||
ticket: multi-frontend-serializable-ir
|
||||
title: Audit public IRBackend contract shape
|
||||
status: done
|
||||
created: 2026-07-15
|
||||
ref_decisions: [DEC-0044]
|
||||
tags: [compiler, compiler-general, ir, backend, serialization, multi-frontend]
|
||||
---
|
||||
|
||||
## Briefing
|
||||
|
||||
`DEC-0044` requires the public `IRBackend` handoff to remain an acyclic, deterministic data graph. Before adding broad tests or changing models, the current public contract must be audited and classified.
|
||||
|
||||
## Objective
|
||||
|
||||
Produce a concrete audit of public `IRBackend` contract types and classify each exposed field, record component, constructor parameter, and public method return/parameter as allowed, forbidden, or requiring a later correction plan.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Accepted decision: `DEC-0044`.
|
||||
- Recommended predecessor: `PLN-0119`, so the audit uses the same terminology as the spec.
|
||||
- Existing model package: `prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/models`.
|
||||
- Existing guardrail test: `prometeu-compiler/prometeu-frontend-api/src/test/java/p/studio/compiler/models/IRBackendExecutableContractTest.java`.
|
||||
|
||||
## Scope
|
||||
|
||||
1. Enumerate all public `IRBackend` handoff types currently treated as contract types.
|
||||
2. Include nested public types such as executable instructions, host-call metadata, intrinsic metadata, reserved metadata surfaces, origins, globals, synthetic functions, and related enums.
|
||||
3. Inspect public API exposure through fields, record components, constructors, getters, and public methods.
|
||||
4. Classify types from adjacent packages such as identifiers, source spans, source table references, and `ReadOnlyList`.
|
||||
5. Record any concrete leak candidates that must be fixed by `PLN-0123`.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Do not fix leaks in this plan unless the audit itself cannot compile without a tiny supporting test helper.
|
||||
- Do not add a serializer or schema.
|
||||
- Do not expand the public contract beyond what current backend lowering needs.
|
||||
- Do not infer new product rules beyond `DEC-0044`.
|
||||
|
||||
## Execution Method
|
||||
|
||||
1. Build the contract type list from `IRBackendExecutableContractTest.PUBLIC_CONTRACT_TYPES` and compare it with actual public model files under `prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/models`.
|
||||
2. Add missing public contract types to the audit list when they are reachable from `IRBackend`, `IRBackendFile`, executable functions, globals, reserved metadata, or synthetic functions.
|
||||
3. Inspect exposed generic types recursively enough to identify:
|
||||
- frontend-owned package exposure,
|
||||
- callback or functional interface exposure,
|
||||
- service/registry/object graph exposure,
|
||||
- unordered collection exposure,
|
||||
- direct mutable collection exposure,
|
||||
- direct object reference patterns that should become ids,
|
||||
- and nullable fields that are semantically ambiguous.
|
||||
4. Write the audit result in the implementation notes, test assertions, or a short local checklist committed with the implementation. Prefer executable test fixtures where possible; use prose only for items that need human judgment.
|
||||
5. Create a list of concrete fix candidates for `PLN-0123`.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. Every current public `IRBackend` contract type is accounted for.
|
||||
2. The audit identifies which exposed supporting types are intentionally allowed by `DEC-0044`.
|
||||
3. Any violation or ambiguous exposure has an exact file/type/member target for `PLN-0123`.
|
||||
4. No codec, schema, RPC, or external process choice is introduced.
|
||||
|
||||
## Tests
|
||||
|
||||
Run the frontend API test suite or the narrow Gradle test task that executes `IRBackendExecutableContractTest`. If no code changes are made in this plan, verify at minimum that the audit inputs still compile before downstream guardrail plans depend on them.
|
||||
|
||||
## Affected Artifacts
|
||||
|
||||
- `prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/models/...`
|
||||
- `prometeu-compiler/prometeu-frontend-api/src/test/java/p/studio/compiler/models/IRBackendExecutableContractTest.java`
|
||||
- Optional implementation note or checklist artifact only if executable tests cannot represent part of the audit clearly.
|
||||
@ -1,69 +0,0 @@
|
||||
---
|
||||
id: PLN-0121
|
||||
ticket: multi-frontend-serializable-ir
|
||||
title: Add serializable IRBackend reflection guardrails
|
||||
status: done
|
||||
created: 2026-07-15
|
||||
ref_decisions: [DEC-0044]
|
||||
tags: [compiler, compiler-general, ir, backend, serialization, multi-frontend]
|
||||
---
|
||||
|
||||
## Briefing
|
||||
|
||||
`DEC-0044` requires lightweight guardrails that prevent the public `IRBackend` handoff from exposing non-serializable process-local shapes. Existing tests already prevent PBS type exposure; this plan expands that guardrail to the broader serializability contract.
|
||||
|
||||
## Objective
|
||||
|
||||
Add reflection-based tests that fail when public `IRBackend` contract types expose callbacks, services, mutable/unordered collections, frontend-owned objects, or other forbidden public shapes.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Accepted decision: `DEC-0044`.
|
||||
- Recommended predecessor: `PLN-0119` for spec terminology.
|
||||
- Recommended predecessor: `PLN-0120` for the complete contract type list and allowed supporting type classification.
|
||||
- Existing test: `prometeu-compiler/prometeu-frontend-api/src/test/java/p/studio/compiler/models/IRBackendExecutableContractTest.java`.
|
||||
|
||||
## Scope
|
||||
|
||||
1. Extend the public contract type list to cover all current `IRBackend` handoff types found by `PLN-0120`.
|
||||
2. Add reflection checks for forbidden package exposure beyond PBS when the exposed type is frontend-owned.
|
||||
3. Add checks that public API signatures do not expose callbacks, functional interfaces, service-like objects, registries, direct mutable collections, or unordered collection contracts.
|
||||
4. Add an allowlist for value wrappers that are accepted by `DEC-0044`, such as identifier wrappers, spans, enums, strings, primitives, boxed scalar values where already present, and `ReadOnlyList`.
|
||||
5. Keep failure messages actionable by reporting the exact contract type and member.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Do not assert one mandatory serializer.
|
||||
- Do not reject all non-record classes automatically; reject public exposed shapes that violate the decision.
|
||||
- Do not rewrite model classes in this plan except for tiny test-support adjustments.
|
||||
- Do not use ArchUnit or a new dependency unless repository maintainers separately approve it.
|
||||
|
||||
## Execution Method
|
||||
|
||||
1. Refactor `IRBackendExecutableContractTest` only enough to support reusable inspection helpers.
|
||||
2. Keep the existing PBS exposure test intact or fold it into a broader public-contract exposure test with equivalent failure coverage.
|
||||
3. Implement recursive inspection of public fields, record components, public constructors, and public methods.
|
||||
4. Treat generic type arguments as part of the public shape.
|
||||
5. Add explicit classification helpers:
|
||||
- `isAllowedScalarOrValueType`,
|
||||
- `isAllowedCollectionType`,
|
||||
- `isForbiddenCallbackOrServiceShape`,
|
||||
- `isForbiddenFrontendOwnedType`.
|
||||
6. Run the narrow test suite and fix only test logic defects in this plan.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. A public `IRBackend` contract type exposing a callback or functional interface would fail the test.
|
||||
2. A public `IRBackend` contract type exposing `java.util.Map`, `java.util.Set`, mutable list classes, or unordered collection interfaces would fail unless explicitly represented as an ordered contract type.
|
||||
3. A public `IRBackend` contract type exposing frontend-owned AST/parser/token/semantic/editorial objects would fail.
|
||||
4. Failure output names the exact member that violates the contract.
|
||||
5. Existing PBS neutrality guardrail coverage is preserved.
|
||||
|
||||
## Tests
|
||||
|
||||
Run the narrow Gradle test task for `IRBackendExecutableContractTest`. If the repo's Gradle structure makes a narrower invocation unreliable, run the smallest module-level test task for `prometeu-frontend-api`.
|
||||
|
||||
## Affected Artifacts
|
||||
|
||||
- `prometeu-compiler/prometeu-frontend-api/src/test/java/p/studio/compiler/models/IRBackendExecutableContractTest.java`
|
||||
- Potential test-only helpers in the same test package.
|
||||
@ -1,64 +0,0 @@
|
||||
---
|
||||
id: PLN-0122
|
||||
ticket: multi-frontend-serializable-ir
|
||||
title: Prove deterministic IRBackend ordering
|
||||
status: done
|
||||
created: 2026-07-15
|
||||
ref_decisions: [DEC-0044]
|
||||
tags: [compiler, compiler-general, ir, backend, serialization, multi-frontend]
|
||||
---
|
||||
|
||||
## Briefing
|
||||
|
||||
`DEC-0044` requires ordered collections and deterministic output-affecting ordering in the common handoff. The current aggregator already uses ordered lists and insertion-preserving sets in some places; this plan proves the behavior that matters for the public contract.
|
||||
|
||||
## Objective
|
||||
|
||||
Add or extend tests that prove deterministic ordering for `IRBackend` aggregation, table emission, executable functions, metadata surfaces, required capabilities, and any other public handoff list whose order can affect backend lowering or serialized representation.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Accepted decision: `DEC-0044`.
|
||||
- Recommended predecessor: `PLN-0120`, so the test targets follow the audited public contract.
|
||||
- Existing aggregator code: `prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/models/IRBackend.java`.
|
||||
- Existing test: `prometeu-compiler/prometeu-frontend-api/src/test/java/p/studio/compiler/models/IRBackendExecutableContractTest.java`.
|
||||
|
||||
## Scope
|
||||
|
||||
1. Test that `IRBackend.IRBackendAggregator` preserves deterministic file merge order for executable functions, globals, synthetic functions, module pool entries, callable signatures, intrinsic pool entries, reserved metadata surfaces, and required capabilities.
|
||||
2. Test that duplicate or repeated metadata inputs produce stable emitted ordering when the contract permits duplicates.
|
||||
3. Test that table-scoped ids are remapped deterministically from local file tables into aggregate tables.
|
||||
4. Confirm that public handoff APIs expose ordered list contracts, not unordered collections.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Do not define semantic sorting where current contract is explicit merge order.
|
||||
- Do not change function-id assignment in backend lowering unless a deterministic-ordering leak is found and moved to `PLN-0123`.
|
||||
- Do not add serialization snapshots or golden wire-format files.
|
||||
- Do not introduce a new collection library.
|
||||
|
||||
## Execution Method
|
||||
|
||||
1. Extend current aggregation tests in `IRBackendExecutableContractTest` or create a focused companion test in the same package.
|
||||
2. Build at least two `IRBackendFile` fixtures with distinct local module, callable, intrinsic, executable, global, synthetic, metadata, and capability entries.
|
||||
3. Merge the fixtures in a known order and assert emitted aggregate order and remapped ids.
|
||||
4. Repeat the merge with equivalent freshly constructed inputs and assert identical aggregate shape.
|
||||
5. Add a negative or regression-style assertion only if the current API can express a previously unstable shape.
|
||||
6. Keep tests independent from PBS parser, PBS lowering, and backend lowering services.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. Tests prove that public handoff list ordering is deterministic for equivalent admitted inputs.
|
||||
2. Tests prove that aggregate table ids are remapped deterministically.
|
||||
3. Tests do not depend on PBS frontend code.
|
||||
4. No wire format or serializer is introduced.
|
||||
|
||||
## Tests
|
||||
|
||||
Run the narrow Gradle test task for `IRBackendExecutableContractTest` or the smallest module-level `prometeu-frontend-api` test task.
|
||||
|
||||
## Affected Artifacts
|
||||
|
||||
- `prometeu-compiler/prometeu-frontend-api/src/test/java/p/studio/compiler/models/IRBackendExecutableContractTest.java`
|
||||
- Optional companion test under `prometeu-compiler/prometeu-frontend-api/src/test/java/p/studio/compiler/models/`
|
||||
- `prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/models/IRBackend.java` only if a deterministic ordering bug is proven and fixed under `PLN-0123`
|
||||
@ -1,75 +0,0 @@
|
||||
---
|
||||
id: PLN-0123
|
||||
ticket: multi-frontend-serializable-ir
|
||||
title: Fix concrete IRBackend serialization leaks
|
||||
status: done
|
||||
created: 2026-07-15
|
||||
ref_decisions: [DEC-0044]
|
||||
tags: [compiler, compiler-general, ir, backend, serialization, multi-frontend]
|
||||
---
|
||||
|
||||
## Briefing
|
||||
|
||||
`DEC-0044` allows incremental correction of concrete leaks found by audit and guardrail tests. This plan is intentionally last because it must operate on proven violations rather than speculative redesign.
|
||||
|
||||
## Objective
|
||||
|
||||
Fix only the concrete public `IRBackend` serialization leaks identified by `PLN-0120`, `PLN-0121`, or `PLN-0122`, while preserving the accepted contract that no codec or transport is introduced.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Accepted decision: `DEC-0044`.
|
||||
- Required predecessor: `PLN-0120`, to identify exact leak targets.
|
||||
- Required predecessor when tests exist: `PLN-0121`, so non-serializable exposure is protected by tests.
|
||||
- Required predecessor when ordering is involved: `PLN-0122`, so deterministic behavior is protected by tests.
|
||||
|
||||
## Scope
|
||||
|
||||
1. Replace public direct object references with explicit ids or stable symbolic keys when the audit proves they are part of the public handoff and violate `DEC-0044`.
|
||||
2. Replace public unordered or mutable collection exposure with ordered contract surfaces.
|
||||
3. Remove or encapsulate public callback, service, registry, visitor, or process-local lazy value exposure if any exists in the handoff.
|
||||
4. Add typed ids only for concrete leak targets where existing ids or stable symbolic keys are insufficient.
|
||||
5. Preserve backwards-compatible constructors or adapters only when they do not keep the forbidden shape in the public contract.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Do not redesign `IRBackend`.
|
||||
- Do not migrate all textual identities to typed ids unless the audit proves a concrete contract leak.
|
||||
- Do not introduce JSON, Protobuf, schema files, RPC, plugin loading, or process boundaries.
|
||||
- Do not change PBS source semantics or backend lowering behavior except where required to consume the corrected handoff shape.
|
||||
|
||||
## Execution Method
|
||||
|
||||
1. Start from the exact violation list produced by `PLN-0120` and failing tests from `PLN-0121` or `PLN-0122`.
|
||||
2. For each violation, choose the smallest correction that satisfies `DEC-0044`:
|
||||
- direct reference to another handoff object becomes an explicit id or ordered table entry;
|
||||
- unordered collection becomes an ordered list of value entries;
|
||||
- mutable collection exposure becomes `ReadOnlyList` or another existing immutable/read-only contract type;
|
||||
- callback/service exposure is removed from the public handoff and moved behind compiler-side assembly code.
|
||||
3. Update constructors, aggregators, lowerers, and tests that consume the corrected contract.
|
||||
4. Keep PBS-specific changes inside PBS lowering if PBS emitted the old shape.
|
||||
5. Run all relevant frontend API and backend tests after each correction group.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. Every concrete leak identified by predecessor plans is either fixed or explicitly documented as not part of the public `IRBackend` handoff.
|
||||
2. Reflection guardrails from `PLN-0121` pass.
|
||||
3. Deterministic ordering tests from `PLN-0122` pass.
|
||||
4. Existing backend lowering tests continue to pass.
|
||||
5. No codec, schema language, RPC, external process, or plugin runtime is introduced.
|
||||
|
||||
## Tests
|
||||
|
||||
Run:
|
||||
|
||||
1. the `prometeu-frontend-api` tests covering `IRBackend` contract models;
|
||||
2. backend lowering tests that consume `IRBackend`, including `LowerToIRVMServiceTest` when available;
|
||||
3. any conformance or architecture tests touched by the corrected public shape.
|
||||
|
||||
## Affected Artifacts
|
||||
|
||||
- `prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/models/...`
|
||||
- `prometeu-compiler/prometeu-frontend-api/src/test/java/p/studio/compiler/models/...`
|
||||
- `prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/backend/...` only when a corrected handoff shape requires backend consumer updates
|
||||
- `prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/backend/...`
|
||||
- PBS lowering files only when PBS emits a corrected handoff shape
|
||||
Loading…
x
Reference in New Issue
Block a user