Compare commits

...

2 Commits

Author SHA1 Message Date
4d8dcf28bb Merge pull request 'implements PLN-0126' (#20) from dev/multi-frontend-validation-boundaries into master
All checks were successful
JaCoCo Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 61.95% (17766/28676) * Branch Coverage: 52.69% (6860/13019) * Lines of Code: 28676 * Cyclomatic Complexity: 11490 #### Quality Gates Summary Output truncated.
Test / Build skipped: 15, passed: 645
Intrepid/Prometeu/Studio/pipeline/head This commit looks good
Reviewed-on: #20
2026-09-19 00:16:57 +00:00
d7c2ec880f
implements PLN-0126
Some checks are pending
Intrepid/Prometeu/Studio/pipeline/pr-master Build started...
JaCoCo Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 61.95% (17766/28676) * Branch Coverage: 52.69% (6860/13019) * Lines of Code: 28676 * Cyclomatic Complexity: 11490 #### Quality Gates Summary Output truncated.
Test / Build skipped: 15, passed: 645
Intrepid/Prometeu/Studio/pipeline/head This commit looks good
Publish the language-versus-platform validation matrix in compiler-general
specs, retitle spec 19, and recut PBS diagnostics so common structural
failures are not PBS coverage.

Housekeep DSC-0060 with LSN-0063.
2026-09-19 01:11:50 +01:00
10 changed files with 323 additions and 100 deletions

View File

@ -1,10 +1,10 @@
{"type":"meta","next_id":{"DSC":66,"AGD":69,"DEC":47,"PLN":126,"LSN":63,"CLSN":1}} {"type":"meta","next_id":{"DSC":66,"AGD":69,"DEC":48,"PLN":127,"LSN":64,"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-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-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":[]} {"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":[]}
{"type":"discussion","id":"DSC-0062","status":"done","ticket":"multi-frontend-pvm-neutrality","title":"Neutralidade da PVM e identificacao PBX independente de PBS","created_at":"2026-07-15","updated_at":"2026-09-18","tags":["vm-arch","runtime","pvm","pbx","compiler","multi-frontend"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0061","file":"discussion/lessons/DSC-0062-multi-frontend-pvm-neutrality/LSN-0061-pbx-runtime-boundary.md","status":"done","created_at":"2026-09-18","updated_at":"2026-09-18"}]} {"type":"discussion","id":"DSC-0062","status":"done","ticket":"multi-frontend-pvm-neutrality","title":"Neutralidade da PVM e identificacao PBX independente de PBS","created_at":"2026-07-15","updated_at":"2026-09-18","tags":["vm-arch","runtime","pvm","pbx","compiler","multi-frontend"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0061","file":"discussion/lessons/DSC-0062-multi-frontend-pvm-neutrality/LSN-0061-pbx-runtime-boundary.md","status":"done","created_at":"2026-09-18","updated_at":"2026-09-18"}]}
{"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-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-0060","status":"done","ticket":"multi-frontend-validation-boundaries","title":"Separar validacoes de linguagem e validacoes de plataforma","created_at":"2026-07-15","updated_at":"2026-09-19","tags":["compiler","compiler-general","compiler-pbs","backend","validation","multi-frontend"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0063","file":"discussion/lessons/DSC-0060-multi-frontend-validation-boundaries/LSN-0063-language-vs-platform-validation-ownership.md","status":"done","created_at":"2026-09-19","updated_at":"2026-09-19"}]}
{"type":"discussion","id":"DSC-0059","status":"done","ticket":"multi-frontend-common-lifecycle","title":"Extrair lifecycle comum das responsabilidades do frontend PBS","created_at":"2026-07-15","updated_at":"2026-09-19","tags":["compiler","compiler-general","compiler-pbs","lifecycle","backend","multi-frontend"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0062","file":"discussion/lessons/DSC-0059-multi-frontend-common-lifecycle/LSN-0062-common-lifecycle-assembly-stage.md","status":"done","created_at":"2026-09-19","updated_at":"2026-09-19"}]} {"type":"discussion","id":"DSC-0059","status":"done","ticket":"multi-frontend-common-lifecycle","title":"Extrair lifecycle comum das responsabilidades do frontend PBS","created_at":"2026-07-15","updated_at":"2026-09-19","tags":["compiler","compiler-general","compiler-pbs","lifecycle","backend","multi-frontend"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0062","file":"discussion/lessons/DSC-0059-multi-frontend-common-lifecycle/LSN-0062-common-lifecycle-assembly-stage.md","status":"done","created_at":"2026-09-19","updated_at":"2026-09-19"}]}
{"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-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-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"}]}

View File

@ -0,0 +1,129 @@
---
id: LSN-0063
ticket: multi-frontend-validation-boundaries
title: Language vs platform validation ownership
created: 2026-09-19
tags: [compiler, compiler-general, compiler-pbs, backend, validation, multi-frontend]
---
# Language vs platform validation ownership
## Original Problem
PBS mixed two kinds of rejection. Some failures only make sense with the
language: syntax, types, markers, barrel files, imports. Others belong to any
executable frontend: malformed `IRBackend`, invalid lifecycle declarations,
missing assembled wrappers, host-capability identity, bytecode/preload.
Without an ownership rule, the next frontend would copy PBS validators, or the
common layer would start knowing `[Init]`, barrel, and `E_SEM_*`. Spec 19 was
still titled as PBS verification, and the PBS diagnostics catalog listed
wrapper and boot-guard failures as PBS coverage.
Lifecycle assembly had already moved (`LSN-0062`). That proved the pattern. It
did not inventory the rest.
## Consolidated Decision
A validation lives at the lowest layer that understands the failure without
knowing the source language.
- Language: needs AST, tokens, a language marker, a barrel, or another source
rule.
- Platform: can be checked on `IRBackend`, `IRLifecycleDeclaration`, IRVM, PBX,
host/capability tables, or ids.
The discussion published that matrix. It did not extract a generic
validator-core and did not move validators whose common contract is not closed.
Host admission is split. PBS owns the source shape of `[Host]` and
`[Capability]`. Platform owns canonical `(module, name, version)` identity and
capability consistency once those facts exist on `IRReservedMetadata`. The
current validator may stay in the PBS package until a later plan. `E_HOST_*`
is not eternal PBS semantics.
The same fact may exist on both sides with distinct identities. PBS can report
`E_SEM_MISSING_PROJECT_FRAME`; the common layer still rejects an executable
declaration with no frame root.
Platform codes are `COMMON_*`, `LOWER_IRVM_*`, or `MARSHAL_*`. PBS keeps
`E_PARSE_*`, `E_SEM_*`, `E_LINK_*`, and `E_HOST_*`. Copy origin/span when
present; a missing origin is a structural error, not a reason to invent a span.
Linking and barrel stay language-owned. `Addressable` is platform-owned and was
classified only. SDK canonical source and the broad architectural harness stay
on adjacent discussions.
## Final Implementation
The work was editorial and test-facing.
Spec 19 is now `Compiler Verification and Safety Checks Specification`. Gates
S-U and S-I are unchanged. Section 11 states the classification rule, the
English ownership matrix, diagnostic identity, dual reporting, and the
host-admission split. It explicitly refuses validator-core extraction and
package moves.
PBS diagnostics spec 12 keeps marker, syntax, semantics, linking, and
host-attribute coverage. Common structural failures now point at spec 19
section 11 and spec 20 instead of appearing as PBS required coverage.
Spec 20 cross-references that same compiler-general ownership. The conformance
matrix added `G19-11.1` through `G19-11.6` and `PBS12-11`.
`CommonBackendArchitectureTest` now guards `backend/`, `lifecycle/`, and all
common pipeline stages. `ValidationOwnershipSpecTest` locks the title, matrix,
and PBS recut.
`PbsHostAdmissionValidator` remains under `p.studio.compiler.pbs`. No linking
or asset production code moved.
## Examples
Language-owned:
- parse errors;
- `[Init]` / `[Frame]` signature and colocation;
- barrel and import failures;
- `host call not allowed during init`.
Platform-owned and already implemented:
- invalid `IRLifecycleDeclaration`;
- assembled wrapper, boot guard, and synthetic origin preconditions;
- IRVM and marshal rejection families.
Classified as platform, not moved:
- canonical host-binding identity on `IRReservedMetadata`;
- `Addressable` / asset path.
Dual reporting:
- missing `[Frame]` in PBS source is `E_SEM_MISSING_PROJECT_FRAME`;
- an executable declaration without frame root is a common structural error.
## Pitfalls
- Do not treat “classified as platform” as “move the class now.” Host admission
still waits on the SDK source discussion.
- Do not merge language and platform failures into one hybrid code. Two
identities are cheaper than a lost message.
- Do not put PBS governance or PBS diagnostics in charge of compiler-general
safety gates.
- Do not scan PBS frontend sources with the platform architecture guard. The
guard is for common validators, not for the language package that must remain.
- Do not invent a validator-core because several common checks exist. They
already live on their stages.
## References
- Decision: `DEC-0047`
- Plan: `PLN-0126`
- Related lesson: `LSN-0062` - Common lifecycle assembly after frontend declaration
- Related lesson: `LSN-0059` - Common IRBackend handoff and backend guardrails
- `docs/specs/compiler/19. Verification and Safety Checks Specification.md`
- `docs/specs/compiler-languages/pbs/12. Diagnostics Specification.md`
- `docs/specs/compiler/20. IRBackend to IRVM Lowering Specification.md`
- `docs/specs/compiler/22. Backend Spec-to-Test Conformance Matrix.md`
- `prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/specs/ValidationOwnershipSpecTest.java`
- `prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/specs/CommonBackendArchitectureTest.java`

View File

@ -1,76 +0,0 @@
---
id: AGD-0063
ticket: multi-frontend-validation-boundaries
title: Separar validacoes de linguagem e validacoes de plataforma
status: open
created: 2026-07-15
resolved:
decision:
tags: [compiler, compiler-general, compiler-pbs, backend, validation, multi-frontend]
---
# Agenda - Separar validacoes de linguagem e plataforma
## Objetivo
Domain owner: `compiler/general`, com impacto em `compiler/pbs`.
Definir onde cada validacao deve viver: PBS para sintaxe e semantica da linguagem; compiler core/backend para entrypoints, exports, hostcalls, capabilities, layouts, IR e bytecode.
## Contexto atual
O PBS concentra parsing, semantica, lowering e algumas validacoes que podem ser universais. O backend ja possui validadores para IRVM, bytecode e precondicoes de lowering.
## Escopo
- Mapear diagnostics e validacoes atuais.
- Classificar cada uma como linguagem ou plataforma.
- Definir regra: colocar a validacao no nivel mais baixo que a compreende sem conhecer a linguagem.
## Fora de escopo
- Reescrever todas as mensagens diagnosticas.
- Mudar codigos de erro sem necessidade.
- Transferir validacoes antes de existir contrato comum suficiente.
## Arquivos e componentes a inspecionar
- `prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/semantics/...`
- `prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/backend/...`
- `prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/backend/...`
- `docs/specs/compiler/19. Verification and Safety Checks Specification.md`
- `docs/specs/compiler-languages/pbs/12. Diagnostics Specification.md`
## Alteracoes propostas
Opcao A: criar matriz de ownership de validacoes antes de mover codigo.
Opcao B: mover validacoes junto com lifecycle/IR quando cada fronteira for tocada.
Recomendacao inicial: matriz primeiro; migracao so quando uma decisao posterior fechar lifecycle e IR.
## Estrategia de implementacao
Auditar testes de erro existentes, agrupar por origem, decidir ownership e adicionar testes de regressao para impedir que o backend importe PBS.
## Testes necessarios
- Testes PBS para erros de sintaxe/semantica continuam no frontend.
- Testes comuns para IR malformada, hostcall inexistente, export duplicado e lifecycle invalido.
- Teste arquitetural de ausencia de imports PBS em validadores comuns.
## Criterios de aceitacao
- Validacoes da plataforma sao expressas sem conceitos PBS.
- Validacoes PBS continuam preservadas e especificas.
## Riscos
- Perder qualidade de diagnostico ao mover validacao para camada comum.
- Duplicar validacoes em vez de estabelecer ownership.
## Decisoes que devem ser registradas
- Matriz de validacoes e ownership.
- Politica de diagnosticos quando o erro comum ainda precisa de source span de frontend.

View File

@ -82,7 +82,8 @@ The following inputs are already fixed elsewhere and must not be contradicted he
- Stable source span metadata is required at the token level and must remain useful to later diagnostics. - Stable source span metadata is required at the token level and must remain useful to later diagnostics.
- Traps are fatal runtime outcomes rather than a recoverable userland diagnostic flow. - Traps are fatal runtime outcomes rather than a recoverable userland diagnostic flow.
- Qualitative cost facts such as retention-bearing operations and host-boundary crossings are normative, but quantitative performance metrics are not. - Qualitative cost facts such as retention-bearing operations and host-boundary crossings are normative, but quantitative performance metrics are not.
- Topic `19` requires deterministic diagnostics for globals, lifecycle markers, init admission, and published-wrapper structural failures. - PBS requires deterministic diagnostics for source-form globals, lifecycle markers, and init admission.
- Published-wrapper, boot-guard, synthetic-origin, and invalid-lifecycle-declaration failures are compiler-general. See `docs/specs/compiler/19. Verification and Safety Checks Specification.md` section 11 and `docs/specs/compiler/20. IRBackend to IRVM Lowering Specification.md`.
## 6. Required Diagnostic Phases ## 6. Required Diagnostic Phases
@ -97,6 +98,8 @@ PBS-facing tooling must distinguish at least the following external diagnostic p
`linking` is a first-class phase in the external diagnostics contract and must not be collapsed away into a generic resolution bucket. `linking` is a first-class phase in the external diagnostics contract and must not be collapsed away into a generic resolution bucket.
The `host-binding/capability admission` phase covers the source shape of `[Host]` and `[Capability]`. Canonical host-binding identity and capability consistency over `IRReservedMetadata` are platform-owned and are not moved by this specification.
This document does not require one finer-grained public phase split for verifier internals, artifact offsets, or transport-specific backend stages beyond what is stated here. This document does not require one finer-grained public phase split for verifier internals, artifact offsets, or transport-specific backend stages beyond what is stated here.
## 7. Required Diagnostic Identity, Payload, and Attribution ## 7. Required Diagnostic Identity, Payload, and Attribution
@ -180,7 +183,7 @@ At minimum, the PBS diagnostics baseline must cover:
5. malformed, unauthorized, or capability-rejected host usage required by `6.2. Host ABI Binding and Loader Resolution Specification.md` and `7. Cartridge Manifest and Runtime Capabilities Specification.md`, 5. malformed, unauthorized, or capability-rejected host usage required by `6.2. Host ABI Binding and Loader Resolution Specification.md` and `7. Cartridge Manifest and Runtime Capabilities Specification.md`,
6. source-attributable backend-originated failures that remain user-actionable under normative lowering or load-facing rules. 6. source-attributable backend-originated failures that remain user-actionable under normative lowering or load-facing rules.
7. dependency-scoped fail-fast admission at frontend boundary: when one module is rejected, modules that import it (directly or transitively) must not be emitted, while diagnostics collection for independent modules must continue. 7. dependency-scoped fail-fast admission at frontend boundary: when one module is rejected, modules that import it (directly or transitively) must not be emitted, while diagnostics collection for independent modules must continue.
8. lifecycle and globals diagnostics required by topic `19`, including: 8. lifecycle-marker and source-form global diagnostics, including:
- `global initializer uses unsupported form`, - `global initializer uses unsupported form`,
- `global dependency cycle detected`, - `global dependency cycle detected`,
- `global import must resolve through a global barrel entry`, - `global import must resolve through a global barrel entry`,
@ -195,14 +198,7 @@ At minimum, the PBS diagnostics baseline must cover:
- `Init attribute target invalid`, - `Init attribute target invalid`,
- `InitAllowed is valid only on SDK host methods`, - `InitAllowed is valid only on SDK host methods`,
- `host call not allowed during init`. - `host call not allowed during init`.
9. common lifecycle structural diagnostics owned by lifecycle assembly and backend preconditions, including: 9. compiler-general lifecycle-assembly and IRVM-precondition failures, which this PBS catalog MUST NOT claim as PBS required coverage; see `docs/specs/compiler/19. Verification and Safety Checks Specification.md` section 11 and `docs/specs/compiler/20. IRBackend to IRVM Lowering Specification.md`.
- invalid or unresolved lifecycle declaration ids and roles,
- missing frame root on an executable declaration,
- frontend-preassembled derived lifecycle artifacts,
- `synthetic wrapper entrypoint missing`,
- `published entrypoint is not function index 0`,
- `hidden boot guard is missing`,
- `synthetic callable origin missing`.
10. symbolic asset-reference diagnostics required by backend-owned `Addressable` resolution, including: 10. symbolic asset-reference diagnostics required by backend-owned `Addressable` resolution, including:
- unresolved terminal asset reference, - unresolved terminal asset reference,
- namespace-versus-terminal asset misuse, - namespace-versus-terminal asset misuse,

View File

@ -1,18 +1,21 @@
# PBS Verification and Safety Checks Specification # Compiler Verification and Safety Checks Specification
Status: Draft v1 (Quality-Gate Baseline) Status: Draft v1 (Quality-Gate Baseline)
Applies to: test-backed safety gates for backend compiler stages and integration regression safety checks against runtime Applies to: test-backed safety gates for common compiler stages, validation ownership across executable frontends, and integration regression safety checks against runtime
## 1. Purpose ## 1. Purpose
This document defines the minimum safety/verification quality gates that must be enforced for executable backend pipelines. This document defines the minimum safety/verification quality gates that must be enforced for executable compiler pipelines, and the ownership rule that separates language validation from platform validation.
Its purpose is to keep safety measurable and deterministic across: Its purpose is to keep safety measurable and deterministic across:
- lowering, - lowering,
- optimization, - optimization,
- emission, - emission,
- and runtime integration boundaries. - runtime integration boundaries,
- and the classification of diagnostics that every executable frontend must obey.
PBS is the current executable frontend. It is an example, not the owner of this specification.
## 2. Scope ## 2. Scope
@ -20,37 +23,41 @@ This document defines:
- mandatory compiler-stage safety checks for executable pipeline stages, - mandatory compiler-stage safety checks for executable pipeline stages,
- conditional integration safety regression checks against runtime line, - conditional integration safety regression checks against runtime line,
- and evidence requirements for safety-related support claims. - evidence requirements for safety-related support claims,
- and validation-ownership rules that apply to all executable frontends.
This document does not define: This document does not define:
- full runtime verifier algorithm internals, - full runtime verifier algorithm internals,
- formal proof of all runtime safety properties, - formal proof of all runtime safety properties,
- or one mandatory verifier/optimizer architecture. - one mandatory verifier/optimizer architecture,
- PBS syntax or static-semantics catalogs,
- or a generic validator-core package.
## 3. Authority and Precedence ## 3. Authority and Precedence
Normative precedence: Normative precedence:
1. `docs/pbs/specs/2. Governance and Versioning.md` 1. Runtime authority (`docs/specs/hardware/topics/chapter-2.md`, `chapter-3.md`, `chapter-9.md`, `chapter-12.md`, `chapter-16.md`)
2. `docs/pbs/specs/12. Diagnostics Specification.md` 2. Bytecode authority (`docs/specs/bytecode/ISA_CORE.md`)
3. `20. IRBackend to IRVM Lowering Specification.md` 3. `20. IRBackend to IRVM Lowering Specification.md`
4. `21. IRVM Optimization Pipeline Specification.md` 4. `21. IRVM Optimization Pipeline Specification.md`
5. `15. Bytecode and PBX Mapping Specification.md` 5. `15. Bytecode and PBX Mapping Specification.md`
6. `13. Conformance Test Specification.md` 6. `13. Conformance Test Specification.md`
7. This document 7. This document
8. Frontend diagnostics specifications, including `docs/specs/compiler-languages/pbs/12. Diagnostics Specification.md`, for language-owned coverage only
If a rule here conflicts with higher-precedence authorities, it is invalid. If a rule here conflicts with a higher-precedence authority, it is invalid. Frontend diagnostics documents MUST NOT redefine compiler-general safety gates or platform validation ownership.
## 4. Normative Inputs ## 4. Normative Inputs
This document depends on: This document depends on:
- `docs/pbs/specs/12. Diagnostics Specification.md`
- `13. Conformance Test Specification.md` - `13. Conformance Test Specification.md`
- `15. Bytecode and PBX Mapping Specification.md` - `15. Bytecode and PBX Mapping Specification.md`
- `20. IRBackend to IRVM Lowering Specification.md` - `20. IRBackend to IRVM Lowering Specification.md`
- `21. IRVM Optimization Pipeline Specification.md` - `21. IRVM Optimization Pipeline Specification.md`
- `docs/specs/compiler-languages/pbs/12. Diagnostics Specification.md` as the current frontend diagnostics catalog, not as the owner of this specification
## 5. Safety Gate Model ## 5. Safety Gate Model
@ -133,3 +140,74 @@ This document is healthy when:
2. executable backends have explicit S-I status (`pass`/`fail`/`deferred`), 2. executable backends have explicit S-I status (`pass`/`fail`/`deferred`),
3. integration safety regressions are preserved in tests, 3. integration safety regressions are preserved in tests,
4. and safety-related support claims remain evidence-backed. 4. and safety-related support claims remain evidence-backed.
## 11. Validation Ownership
A validation MUST live at the lowest layer that understands the failure without knowing the source language.
- A check is language-owned if it needs AST, tokens, a language marker, a barrel, or another source-language rule.
- A check is platform-owned if it can be performed on `IRBackend`, `IRLifecycleDeclaration`, IRVM, PBX, host/capability tables, or ids.
Adding a validation MUST record:
1. the input artifact the check reads;
2. whether that artifact is language source/AST/marker or a common contract;
3. the matrix owner;
4. the code family (`E_PARSE_*` / `E_SEM_*` / `E_LINK_*` / `E_HOST_*` versus `COMMON_*` / `LOWER_IRVM_*` / `MARSHAL_*`);
5. whether the span comes from a common-contract origin or from language tokens/AST.
If item 2 is both, the implementation MUST emit two diagnostics with distinct identities, not one hybrid.
### 11.1 Diagnostic identity and span
Platform diagnostics MUST use `COMMON_*`, `LOWER_IRVM_*`, or `MARSHAL_*` codes and the phase of the pipeline stage that reports them.
PBS MUST keep its current `E_PARSE_*`, `E_SEM_*`, `E_LINK_*`, and `E_HOST_*` codes.
This specification MUST NOT rewrite diagnostic messages or renumber existing codes.
Common code MUST copy origin/span when the declaration, instruction, or metadata carries one. A missing origin MUST be a structural error. Implementations MUST NOT invent a span.
The same fact MAY exist on both sides. PBS explains the language rule; the common layer rejects an invalid handoff even when the frontend has no PBS markers. The two errors MUST keep distinct identities. Example: `E_SEM_MISSING_PROJECT_FRAME` and a missing frame root on an executable `IRLifecycleDeclaration`.
### 11.2 Initial ownership matrix
| Family | Owner | Status | Notes |
| --- | --- | --- | --- |
| Parse / syntax (`ParseErrors`) | `compiler/pbs` | language | remains |
| Type, flow, declaration, const, and source-form global semantics | `compiler/pbs` | language | remains |
| Markers `[Init]`, `[Frame]`, `InitAllowed`, signature, colocation | `compiler/pbs` | language | already split by lifecycle assembly |
| `host call not allowed during init` | `compiler/pbs` | language | marker/source rule |
| PBS linking (`PbsLinkErrors`, barrel, import, visibility) | `compiler/pbs` | language | do not extract |
| Source shape of `[Host]` / `[Capability]` | `compiler/pbs` | language | host-admission split |
| Canonical host-binding identity and capability over `IRReservedMetadata` | `compiler/general` | platform | classified; validator remains in the PBS package until a later plan |
| Lifecycle assembler | `compiler/general` | platform | already implemented |
| IRVM preconditions for wrapper, boot guard, origin | `compiler/general` | platform | already implemented |
| `IRVMValidator`, lowering, marshal/bytecode | `compiler/general` | platform | already implemented |
| `Addressable` / asset path | `compiler/general` | platform | classified; no extra migration in this specification |
| Gates S-U/S-I | `compiler/general` | platform | this document |
### 11.3 Host admission, assets, and linking
Host admission is split:
- language owns the source shape of `[Host]` and `[Capability]`;
- platform owns canonical binding identity `(module, name, version)`, unknown capability, undeclared capability, and inconsistent binding once those facts exist on `IRReservedMetadata`.
`PbsHostAdmissionValidator` MAY remain in the PBS package until a later plan. `E_HOST_*` MUST NOT be treated as eternal PBS semantics.
`Addressable` / asset-path resolution is platform-owned. This specification classifies it and MUST NOT move additional asset code.
PBS linking, barrel files, and `PbsLinkErrors` remain language-owned. `ResolveDeps` does not authorize extracting them.
### 11.4 What this section does not authorize
This specification MUST NOT be read as authorizing:
- a generic validator-core package;
- moving `PbsHostAdmissionValidator` into a common package;
- moving asset-resolution production code;
- extracting PBS linking;
- or reopening lifecycle-assembly ownership.
Platform validators MUST NOT import `p.studio.compiler.pbs` and MUST NOT discover roles from `__pbs.` prefixes.

View File

@ -151,6 +151,8 @@ Lowering from `IRBackend` to `IRVM` may start only when:
Declaration validation, role uniqueness, explicit order, and rejection of frontend-preassembled derived artifacts belong to `LifecycleAssemblerService`. `IRBackend -> IRVM` MUST keep only backend preconditions on the assembled graph, such as published-wrapper identity, synthetic origin presence, and hidden boot-guard presence. It MUST NOT reconstruct lifecycle order from callable names. Declaration validation, role uniqueness, explicit order, and rejection of frontend-preassembled derived artifacts belong to `LifecycleAssemblerService`. `IRBackend -> IRVM` MUST keep only backend preconditions on the assembled graph, such as published-wrapper identity, synthetic origin presence, and hidden boot-guard presence. It MUST NOT reconstruct lifecycle order from callable names.
Those common structural diagnostics are compiler-general. Classification, code families, and dual language/platform reporting are owned by `docs/specs/compiler/19. Verification and Safety Checks Specification.md` section 11. They MUST NOT be catalogued as PBS-facing required coverage.
## 6. IRVM Model Obligations ## 6. IRVM Model Obligations
`IRVM` v1 is a quasi-ISA backend form: `IRVM` v1 is a quasi-ISA backend form:

View File

@ -3,7 +3,7 @@
Status: Draft v1 (Traceability Baseline) Status: Draft v1 (Traceability Baseline)
Applies to: compiler/backend conformance traceability for canonical stage order and entrypoint-specific contracts Applies to: compiler/backend conformance traceability for canonical stage order and entrypoint-specific contracts
Last Updated: 2026-09-18 Last Updated: 2026-09-19
## 1. Purpose ## 1. Purpose
@ -40,6 +40,13 @@ to concrete positive/negative test evidence and current status.
| G19-5.2.6 | Gate S-I MUST reject missing capability at load-time. | N/A | `BackendGateIIntegrationTest#gateI_rejectMissingCapability` | pass | | | G19-5.2.6 | Gate S-I MUST reject missing capability at load-time. | N/A | `BackendGateIIntegrationTest#gateI_rejectMissingCapability` | pass | |
| G19-5.2.7 | Gate S-I MUST cover valid VM-owned intrinsic path. | `BackendGateIIntegrationTest#gateI_validIntrinsicPath` | N/A | pass | | | G19-5.2.7 | Gate S-I MUST cover valid VM-owned intrinsic path. | `BackendGateIIntegrationTest#gateI_validIntrinsicPath` | N/A | pass | |
| G19-5.2.8 | Gate S-I MUST cover repeatability across runtime line. | `RuntimeBackedCompatibilityAdapterTest#checkMustPassInStrictModeWhenRuntimeCommandIsValid`; `RuntimeBackedCompatibilityAdapterTest#checkMustBeRepeatableAcrossDeclaredRuntimeLinesInStrictMode` | `RuntimeBackedCompatibilityAdapterTest#checkMustFailInStrictModeWhenRuntimeCommandIsUnavailable` | pass | Multi-line repeatability is asserted with strict runtime-backed checks over distinct declared runtime lines. | | G19-5.2.8 | Gate S-I MUST cover repeatability across runtime line. | `RuntimeBackedCompatibilityAdapterTest#checkMustPassInStrictModeWhenRuntimeCommandIsValid`; `RuntimeBackedCompatibilityAdapterTest#checkMustBeRepeatableAcrossDeclaredRuntimeLinesInStrictMode` | `RuntimeBackedCompatibilityAdapterTest#checkMustFailInStrictModeWhenRuntimeCommandIsUnavailable` | pass | Multi-line repeatability is asserted with strict runtime-backed checks over distinct declared runtime lines. |
| G19-11.1 | A validation MUST live at the lowest layer that understands the failure without knowing the source language. | `ValidationOwnershipSpecTest#spec19MustBeCompilerGeneralAndPublishValidationOwnership` | N/A | pass | Spec 19 section 11 states the classification rule. |
| G19-11.2 | Spec 19 MUST publish the validation ownership matrix. | `ValidationOwnershipSpecTest#spec19MustBeCompilerGeneralAndPublishValidationOwnership` | N/A | pass | Matrix families include parse/syntax, PBS linking, and lifecycle assembler. |
| G19-11.3 | Platform diagnostics MUST use `COMMON_*` / `LOWER_IRVM_*` / `MARSHAL_*` and MUST copy origin/span when present. | `ValidationOwnershipSpecTest#spec19MustBeCompilerGeneralAndPublishValidationOwnership`; `LifecycleAssemblerServiceTest#assembleMustRejectMissingFrameRootWithoutRepair` | N/A | pass | Code families and span policy are normative in spec 19 section 11.1. |
| G19-11.4 | The same fact MAY exist as a language diagnostic and a platform diagnostic with distinct identities. | `ValidationOwnershipSpecTest#spec19MustBeCompilerGeneralAndPublishValidationOwnership` | N/A | pass | Dual reporting is required when a check reads both source and common contract. |
| G19-11.5 | Host admission MUST split source attribute shape from canonical `IRReservedMetadata` identity without moving the PBS validator in this plan. | `ValidationOwnershipSpecTest#spec19MustBeCompilerGeneralAndPublishValidationOwnership` | N/A | pass | Classified as platform; validator remains in the PBS package. |
| G19-11.6 | Platform validators MUST NOT import PBS packages or match `__pbs.` prefixes. | `CommonBackendArchitectureTest#commonBackendMustNotImportPbsFrontendPackages`; `CommonBackendArchitectureTest#commonLifecycleAndBackendMustNotDiscoverRolesFromPbsNamePrefixes` | N/A | pass | Guard covers backend, lifecycle, and all common pipeline stages. |
| PBS12-11 | PBS diagnostics MUST NOT claim common structural lifecycle/IRVM failures as PBS required coverage. | `ValidationOwnershipSpecTest#pbsDiagnosticsMustNotClaimCommonStructuralFailures` | N/A | pass | PBS spec 12 points those failures at spec 19 section 11 and spec 20. |
| G20-4.1.1 | `IRBackend` MUST be the common frontend-to-backend executable handoff. | `LowerToIRVMServiceTest#lowerMustAcceptManuallyConstructedCommonIRBackend` | N/A | pass | Direct backend lowering from manually constructed common IRBackend proves PBS parser/frontend services are not required. | | G20-4.1.1 | `IRBackend` MUST be the common frontend-to-backend executable handoff. | `LowerToIRVMServiceTest#lowerMustAcceptManuallyConstructedCommonIRBackend` | N/A | pass | Direct backend lowering from manually constructed common IRBackend proves PBS parser/frontend services are not required. |
| G20-4.1.2 | Common backend code MUST NOT depend on `p.studio.compiler.pbs`. | `CommonBackendArchitectureTest#commonBackendMustNotImportPbsFrontendPackages` | N/A | pass | Source-level architectural guard rejects PBS frontend imports in common backend packages. | | G20-4.1.2 | Common backend code MUST NOT depend on `p.studio.compiler.pbs`. | `CommonBackendArchitectureTest#commonBackendMustNotImportPbsFrontendPackages` | N/A | pass | Source-level architectural guard rejects PBS frontend imports in common backend packages. |
| G20-4.1.3 | Public `IRBackend` contract MUST NOT expose PBS AST, token, parser, semantic, or editorial types. | `IRBackendExecutableContractTest#publicIRBackendContractMustNotExposePbsTypes` | N/A | pass | Reflection guard covers public contract fields, constructors, methods, and record components. | | G20-4.1.3 | Public `IRBackend` contract MUST NOT expose PBS AST, token, parser, semantic, or editorial types. | `IRBackendExecutableContractTest#publicIRBackendContractMustNotExposePbsTypes` | N/A | pass | Reflection guard covers public contract fields, constructors, methods, and record components. |

View File

@ -36,6 +36,13 @@ class BackendConformanceMatrixSpecTest {
"G19-5.2.6", "G19-5.2.6",
"G19-5.2.7", "G19-5.2.7",
"G19-5.2.8", "G19-5.2.8",
"G19-11.1",
"G19-11.2",
"G19-11.3",
"G19-11.4",
"G19-11.5",
"G19-11.6",
"PBS12-11",
"G20-4.1.1", "G20-4.1.1",
"G20-4.1.2", "G20-4.1.2",
"G20-4.1.3", "G20-4.1.3",

View File

@ -17,7 +17,7 @@ class CommonBackendArchitectureTest {
private static final List<String> GUARDED_RELATIVE_ROOTS = List.of( private static final List<String> GUARDED_RELATIVE_ROOTS = List.of(
"backend", "backend",
"lifecycle", "lifecycle",
"workspaces/stages/AssembleLifecyclePipelineStage.java"); "workspaces/stages");
private static final String FORBIDDEN_PBS_PACKAGE = "p.studio.compiler.pbs"; private static final String FORBIDDEN_PBS_PACKAGE = "p.studio.compiler.pbs";
private static final String FORBIDDEN_PBS_PREFIX = "__pbs."; private static final String FORBIDDEN_PBS_PREFIX = "__pbs.";

View File

@ -0,0 +1,80 @@
package p.studio.compiler.specs;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
class ValidationOwnershipSpecTest {
private static final String SPEC_19 =
"docs/specs/compiler/19. Verification and Safety Checks Specification.md";
private static final String PBS_SPEC_12 =
"docs/specs/compiler-languages/pbs/12. Diagnostics Specification.md";
private static final List<String> PBS_FORBIDDEN_COMMON_COVERAGE = List.of(
"synthetic wrapper entrypoint missing",
"published entrypoint is not function index 0",
"hidden boot guard is missing",
"synthetic callable origin missing");
@Test
void spec19MustBeCompilerGeneralAndPublishValidationOwnership() throws IOException {
final var content = Files.readString(locateRepoRoot().resolve(SPEC_19));
assertFalse(
content.startsWith("# PBS Verification"),
"spec 19 must not be titled as PBS Verification");
assertTrue(
content.contains("# Compiler Verification and Safety Checks Specification"),
"spec 19 must use the compiler-general title");
assertTrue(content.contains("## 11. Validation Ownership"), "spec 19 must contain Validation Ownership");
assertTrue(
content.contains("lowest layer that understands the failure without knowing the source language"),
"spec 19 must state the classification MUST");
assertTrue(content.contains("Parse / syntax"), "spec 19 matrix must include parse/syntax");
assertTrue(content.contains("PBS linking"), "spec 19 matrix must include PBS linking");
assertTrue(content.contains("Lifecycle assembler"), "spec 19 matrix must include lifecycle assembler");
assertTrue(
content.contains("Canonical host-binding identity"),
"spec 19 matrix must include the host-admission split");
assertTrue(
content.contains("MUST NOT import `p.studio.compiler.pbs`"),
"spec 19 must forbid PBS imports in platform validators");
}
@Test
void pbsDiagnosticsMustNotClaimCommonStructuralFailures() throws IOException {
final var content = Files.readString(locateRepoRoot().resolve(PBS_SPEC_12));
for (final var forbidden : PBS_FORBIDDEN_COMMON_COVERAGE) {
assertFalse(
content.contains(forbidden),
"PBS spec 12 must not list common structural coverage: " + forbidden);
}
assertTrue(
content.contains("docs/specs/compiler/19. Verification and Safety Checks Specification.md"),
"PBS spec 12 must point common structural failures at spec 19");
assertTrue(
content.contains("init function must have signature fn name() -> void"),
"PBS spec 12 must retain lifecycle-marker coverage");
}
private static Path locateRepoRoot() {
var cursor = Path.of(System.getProperty("user.dir")).toAbsolutePath().normalize();
while (cursor != null) {
final var hasDocs = Files.isDirectory(cursor.resolve("docs/specs/compiler"));
final var hasCompiler = Files.isDirectory(cursor.resolve("prometeu-compiler"));
if (hasDocs && hasCompiler) {
return cursor;
}
cursor = cursor.getParent();
}
fail("could not locate repository root from working directory");
throw new IllegalStateException("unreachable");
}
}