diff --git a/docs/compiler/pbs/agendas/19.4. Globals and Lifecycle Lowering to IRBackend/IRVM Agenda.md b/docs/compiler/pbs/agendas/19.4. Globals and Lifecycle Lowering to IRBackend/IRVM Agenda.md index 11e95101..88450968 100644 --- a/docs/compiler/pbs/agendas/19.4. Globals and Lifecycle Lowering to IRBackend/IRVM Agenda.md +++ b/docs/compiler/pbs/agendas/19.4. Globals and Lifecycle Lowering to IRBackend/IRVM Agenda.md @@ -75,6 +75,7 @@ Esta agenda deve produzir direção suficiente para fechar: 5. O wrapper published entrypoint é um callable sintético explícito no graph do frontend? 6. Como manter attribution e diagnostics úteis para código sintético? 7. Que mudanças mínimas precisam acontecer em specs gerais fora de `docs/compiler/pbs`? +8. O lowering deve introduzir uma classe explícita de funções sintéticas com ergonomia própria, em vez de emissão ad hoc? ## Options @@ -122,6 +123,164 @@ Tratar globals como açúcar compilado diretamente para slots/ops sem entidade i Seguir com a **Option A**, salvo impedimento forte de boundary cross-domain. +## Current Direction + +Os pontos abaixo já podem ser tratados como direção fechada desta agenda, salvo objeção nova forte: + +1. globals devem entrar explicitamente no `IRBackend`; +2. o pipeline não deve adiar globals para uma materialização implícita tardia abaixo desse boundary; +3. fragments de init por arquivo, init sintético por módulo, init de projeto e wrapper published entrypoint devem existir como callables sintéticos explícitos; +4. o boot guard deve ser materializado como um global oculto; +5. esse global oculto não pode ser referenciado nem alterado por userland; +6. o wrapper published entrypoint deve existir explicitamente no graph de lowering; +7. o lowering deve seguir direção direta para as operações de globals já suportadas em `IRVM`/VM, isto é, `GET_GLOBAL` e `SET_GLOBAL`; +8. attribution e diagnostics devem preservar separadamente: + - origem em source userland, + - e origem sintética gerada pelo compiler; +9. quando algum erro estrutural ou de lowering surgir em código sintetizado, a superfície sintética deve ser capaz de carregar attribution de volta ao código real que originou aquele trecho; +10. spans e diagnostics devem preferir apontar para código real de userland sempre que essa origem existir; +11. o frontend/lowering deve introduzir uma classe explícita de funções sintéticas com ergonomia própria; +12. a emissão dessas funções não deve ser ad hoc caso a caso. + +## Synthetic Callable Direction + +Esta agenda também fecha a seguinte direção arquitetural: + +1. callables sintéticos não devem ser tratados como acidentes de emissão; +2. eles devem possuir classe/identidade própria no lowering; +3. essa classe deve cobrir pelo menos: + - fragmentos de init por arquivo, + - init sintético por módulo, + - init de projeto, + - wrapper físico publicado; +4. a ergonomia dessa classe própria deve facilitar: + - ordenação, + - attribution, + - debug, + - testes, + - e futuras extensões de lifecycle sem reabrir o modelo básico. + +Também fica fechada a seguinte exigência de diagnóstico: + +1. a superfície sintética precisa carregar origem suficiente para remapear erros ao código real; +2. quando existir origem userland inequívoca, o diagnóstico deve preferir essa origem em vez de um span puramente sintético; +3. spans puramente sintéticos só devem aparecer quando não houver origem real defensável. + +## Hidden Boot Guard Direction + +O boot guard também fica com direção fechada nesta agenda: + +1. ele deve existir como global oculto de programa; +2. ele pertence ao estado interno publicado pelo compiler; +3. userland não pode nomeá-lo, ler seu valor ou alterá-lo; +4. sua única função é garantir a semântica one-shot do bootstrap no wrapper físico. + +## IRBackend Shape Direction + +Esta agenda também fecha o seguinte shape estrutural mínimo para o `IRBackend`. + +### 1. Backend Globals + +O `IRBackend` deve carregar globals explicitamente como entidades estruturais, não apenas como efeitos implícitos no corpo de funções. + +Direção mínima recomendada para cada global: + +- `name` +- `ownerModuleId` +- `type` +- `slot` +- `visibility` +- `isHidden` +- `origin` + +Isso deve cobrir: + +- globals de userland; +- e globals ocultos do compiler, incluindo o boot guard. + +### 2. Backend Callables + +O `IRBackend` deve distinguir explicitamente: + +- callables normais de userland; +- callables sintéticos gerados pelo compiler. + +### 3. Synthetic Callable Kind + +O conjunto mínimo de kinds sintéticos desta agenda deve cobrir: + +- `FILE_INIT_FRAGMENT` +- `MODULE_INIT` +- `PROJECT_INIT` +- `PUBLISHED_FRAME_WRAPPER` + +### 4. Synthetic Origin + +Todo callable ou global sintético deve carregar metadados suficientes para attribution e remapeamento de diagnóstico. + +Direção mínima recomendada: + +- `derivedFromFile` +- `derivedFromModule` +- `derivedFromUserSymbol` +- `primarySpan` +- `fallbackSyntheticLabel` + +### 5. Hidden Global Kind + +O boot guard deve aparecer como global oculto com identidade estrutural explícita, não como convenção informal de nome. + +Direção mínima recomendada: + +- `BOOT_GUARD` + +## Diagnostics and Conformance Direction + +Esta agenda também fecha o seguinte conjunto mínimo de checks estruturais e evidências de conformance. + +### Structural Diagnostics / Validation + +1. `synthetic wrapper entrypoint missing` + - quando o pipeline não conseguir publicar o wrapper exigido. +2. `published entrypoint is not function index 0` + - quando o lowering violar o protocolo físico. +3. `hidden boot guard is missing` + - quando a semântica one-shot exigir o guard e ele não existir. +4. `synthetic callable origin missing` + - quando o lowering gerar callable sintético sem attribution suficiente para diagnóstico defensável. + +### Conformance / Fixture Expectations + +1. fixture com `declare global` + `[Init]` por arquivo + `[Init]` de projeto + `[Frame]`; +2. evidência de geração de: + - file init fragment, + - module init, + - project init, + - published wrapper, + - hidden boot guard; +3. evidência de que o wrapper ocupa `func_id = 0`; +4. evidência de que `FRAME_RET` está no wrapper; +5. evidência de que erro em lowering sintético remapeia para span real quando houver origem de userland defensável. + +## Spec and Learn Propagation Direction + +Esta agenda também fecha a seguinte direção editorial: + +1. specs de lowering devem explicar de forma normativa: + - a classe de callables sintéticos, + - o lifecycle de init no lowering, + - o wrapper publicado, + - o hidden boot guard, + - e a relação desses artefatos com attribution e diagnostics; +2. `learn` deve explicar esse modelo de forma didática com exemplos de código source; +3. `learn` deve mostrar como: + - `declare global`, + - `[Init]` por arquivo, + - `[Init]` de projeto, + - e `[Frame]` + se compõem até virar o wrapper físico publicado; +4. a explicação didática em `learn` deve privilegiar exemplos concretos de source e composição, não apenas descrição abstrata do pipeline. + ## Expected Spec Material Se esta agenda fechar, a propagação esperada atinge pelo menos: @@ -144,4 +303,3 @@ Esta agenda não deve: Depois de fechar esta agenda, abrir ou aprofundar: - `19.5. Diagnostics, Manifest Propagation, and Conformance Coverage Agenda` - diff --git a/docs/compiler/pbs/agendas/19.5. Diagnostics, Manifest Propagation, and Conformance Coverage Agenda.md b/docs/compiler/pbs/agendas/19.5. Diagnostics, Manifest Propagation, and Conformance Coverage Agenda.md index 4c065aeb..8240273d 100644 --- a/docs/compiler/pbs/agendas/19.5. Diagnostics, Manifest Propagation, and Conformance Coverage Agenda.md +++ b/docs/compiler/pbs/agendas/19.5. Diagnostics, Manifest Propagation, and Conformance Coverage Agenda.md @@ -2,7 +2,7 @@ ## Status -Open +Closed ## Parent Agenda @@ -107,6 +107,149 @@ Começar fixtures e diagnostics cedo, mesmo com arquitetura ainda mudando. Seguir com a **Option A**. +## Current Direction + +Os pontos abaixo já podem ser tratados como direção fechada desta agenda, salvo objeção nova forte: + +1. a 19.5 não reabre arquitetura; ela consolida diagnostics, propagation e coverage da série 19; +2. o catálogo final deve ser agrupado por fase, não apenas por ordem histórica das agendas; +3. a propagation final deve nomear explicitamente: + - PBS specs, + - general compiler specs, + - runtime cross-domain owner, + - e `learn`; +4. a conformance matrix mínima deve cobrir: + - positive source flow, + - negative frontend cases, + - negative lowering/structural cases, + - runtime integration. + +## Consolidated Diagnostics Direction + +Esta agenda fecha a seguinte consolidação de diagnósticos por fase. + +### Frontend / Static Semantics + +- `global initializer uses unsupported form` +- `global dependency cycle detected` +- `imported symbol shadows existing visible symbol; alias required` +- `global import must resolve through a global barrel entry` +- `init function must have signature fn name() -> void` +- `frame function must have signature fn name() -> void` +- `multiple module init functions detected` +- `multiple project init functions detected` +- `multiple frame functions detected` +- `missing frame function for executable project` +- `Init attribute target invalid` +- `project init must be colocated with frame` +- `InitAllowed is valid only on SDK host methods` +- `host call not allowed during init` + +### Lowering / Structural Validation + +- `synthetic wrapper entrypoint missing` +- `published entrypoint is not function index 0` +- `hidden boot guard is missing` +- `synthetic callable origin missing` + +### Runtime / Boot Failure + +- `boot failed during module init` +- `boot failed during project init` + +Também fica fechada a seguinte leitura: + +1. diagnósticos de frontend/static semantics são user-facing do compiler; +2. checks de lowering podem aparecer como diagnostics, validation failures ou invariant violations, desde que a falha seja observável e testável; +3. falhas de boot do runtime pertencem à superfície de falha operacional, não ao frontend static diagnostic catalog. + +## Propagation Targets Direction + +Esta agenda fecha a seguinte lista mínima de propagation targets. + +### PBS Specs + +- `3. Core Syntax Specification.md` +- `4. Static Semantics Specification.md` +- `9. Dynamic Semantics Specification.md` +- `11. AST Specification.md` +- `12. Diagnostics Specification.md` +- `13. Lowering IRBackend Specification.md` +- `7. Cartridge Manifest and Runtime Capabilities Specification.md` + +### General Compiler Specs + +- `15. Bytecode and PBX Mapping Specification.md` +- `20. IRBackend to IRVM Lowering Specification.md` + +### Runtime Cross-Domain Owner + +- `../runtime/docs/runtime/agendas/025-cartridge-manifest-entrypoint-removal-and-runtime-protocol.md` + +### Learn + +- um learn consolidado para globals + lifecycle + published wrapper + entrypoint protocol +- com explicação source-first e depois lowering/publication + +## Conformance Matrix Direction + +Esta agenda fecha a seguinte matrix mínima de coverage. + +### Positive Coverage + +Projeto com: + +- `declare global` +- `[Init]` por arquivo +- `[Init]` de projeto +- `[Frame]` + +Assert mínimo: + +- globals aceitos +- ordering aceito +- wrapper publicado +- `func_id = 0` +- `FRAME_RET` no wrapper +- boot guard presente + +### Negative Frontend Coverage + +- `global` com `fn` no initializer +- `global` com `if` +- ciclo entre globals +- collision entre import e `const`/`global`/`service`/`fn` +- `[Init]` com assinatura errada +- `[Frame]` com assinatura errada +- dois `[Frame]` +- dois `project init` +- `project init` fora do arquivo do `[Frame]` +- host call em init sem `[InitAllowed]` +- `[InitAllowed]` em target inválido + +### Negative Lowering Coverage + +- ausência de wrapper publicado +- wrapper fora do índice `0` +- ausência de boot guard +- callable sintético sem origin metadata + +### Runtime Integration Coverage + +- artefato sobe com entrypoint físico `0` +- runtime não depende de export nominal para boot +- boot failure em module init gera falha coerente +- boot failure em project init gera falha coerente + +## Exit Direction + +Esta agenda considera a série 19 pronta para virar execução quando houver: + +1. catálogo consolidado de diagnósticos fechado; +2. propagation targets explicitamente nomeados; +3. conformance matrix mínima aceita; +4. owner explícito para a frente cross-domain de runtime. + ## Expected Spec Material Se esta agenda fechar, a propagação esperada atinge pelo menos: @@ -127,7 +270,8 @@ Esta agenda não deve: ## Next Step -Depois do fechamento desta agenda, a linha `19` fica pronta para: +Esta agenda foi consolidada em: -- virar uma `decision` consolidada em `docs/compiler/pbs/decisions`; -- e então ser decomposta em `pull-request/plan` de execução. +- `docs/compiler/pbs/decisions/Diagnostics, Manifest Propagation, and Conformance Coverage Decision.md` + +Com isso, a família `19` fica pronta para ser decomposta em `pull-request/plan` de execução. diff --git a/docs/compiler/pbs/decisions/Diagnostics, Manifest Propagation, and Conformance Coverage Decision.md b/docs/compiler/pbs/decisions/Diagnostics, Manifest Propagation, and Conformance Coverage Decision.md new file mode 100644 index 00000000..32e65bca --- /dev/null +++ b/docs/compiler/pbs/decisions/Diagnostics, Manifest Propagation, and Conformance Coverage Decision.md @@ -0,0 +1,210 @@ +# Diagnostics, Manifest Propagation, and Conformance Coverage Decision + +Status: Accepted +Date: 2026-03-22 +Related Agenda: `docs/compiler/pbs/agendas/19.5. Diagnostics, Manifest Propagation, and Conformance Coverage Agenda.md` + +## Context + +After closing globals, lifecycle markers, published wrapper ownership, and lowering structure, PBS v1 still needed one final consolidation step for topic `19`. + +The remaining work was no longer architectural debate. +It was operational consolidation across the whole line: + +- which diagnostics are now mandatory, +- which phase owns each failure surface, +- which specs and cross-domain artifacts must be updated, +- and what minimum conformance evidence is required before execution planning begins. + +Important fixed inputs already existed: + +- `19.1` closed the source surface and dependency rules for globals; +- `19.2` closed lifecycle markers, init ordering, and init restrictions; +- `19.3` closed published wrapper ownership, physical entrypoint `0`, and manifest protocol direction; +- `19.4` closed explicit lowering structure, synthetic callable classes, hidden boot guard policy, and lowering-side invariants. + +## Decision + +PBS accepts the following consolidation for topic `19`: + +1. The diagnostics line for family `19` is grouped by phase rather than by historical agenda order. +2. The final propagation line for family `19` must name PBS specs, general compiler specs, runtime cross-domain ownership, and `learn`. +3. The conformance line for family `19` must cover positive flow, negative frontend coverage, negative lowering coverage, and runtime integration. +4. Runtime-side work required by entrypoint protocol changes remains explicitly cross-domain and is owned through: + - `../runtime/docs/runtime/agendas/025-cartridge-manifest-entrypoint-removal-and-runtime-protocol.md` + +## Consolidated Diagnostics + +PBS adopts the following minimum diagnostics and failure surfaces for family `19`. + +### Frontend / Static Semantics + +The compiler must provide, at minimum: + +1. `global initializer uses unsupported form` +2. `global dependency cycle detected` +3. `imported symbol shadows existing visible symbol; alias required` +4. `global import must resolve through a global barrel entry` +5. `init function must have signature fn name() -> void` +6. `frame function must have signature fn name() -> void` +7. `multiple module init functions detected` +8. `multiple project init functions detected` +9. `multiple frame functions detected` +10. `missing frame function for executable project` +11. `Init attribute target invalid` +12. `project init must be colocated with frame` +13. `InitAllowed is valid only on SDK host methods` +14. `host call not allowed during init` + +### Lowering / Structural Validation + +The lowering line must enforce, at minimum: + +1. `synthetic wrapper entrypoint missing` +2. `published entrypoint is not function index 0` +3. `hidden boot guard is missing` +4. `synthetic callable origin missing` + +These may appear as backend diagnostics, validation failures, or invariant violations, as long as the failure is observable and testable. + +### Runtime / Boot Failure + +The runtime-facing failure surface must distinguish, at minimum: + +1. `boot failed during module init` +2. `boot failed during project init` + +These belong to operational boot failure reporting rather than to the static compiler diagnostic catalog. + +## Propagation Targets + +PBS adopts the following minimum propagation line for family `19`. + +### PBS Specs + +This decision must propagate to at least: + +1. `docs/compiler/pbs/specs/3. Core Syntax Specification.md` +2. `docs/compiler/pbs/specs/4. Static Semantics Specification.md` +3. `docs/compiler/pbs/specs/7. Cartridge Manifest and Runtime Capabilities Specification.md` +4. `docs/compiler/pbs/specs/9. Dynamic Semantics Specification.md` +5. `docs/compiler/pbs/specs/11. AST Specification.md` +6. `docs/compiler/pbs/specs/12. Diagnostics Specification.md` +7. `docs/compiler/pbs/specs/13. Lowering IRBackend Specification.md` + +### General Compiler Specs + +This decision must also propagate to at least: + +1. `docs/compiler/general/specs/15. Bytecode and PBX Mapping Specification.md` +2. `docs/compiler/general/specs/20. IRBackend to IRVM Lowering Specification.md` + +### Runtime Cross-Domain Owner + +The runtime half of the protocol change remains explicitly cross-domain and must be tracked through: + +1. `../runtime/docs/runtime/agendas/025-cartridge-manifest-entrypoint-removal-and-runtime-protocol.md` + +### Learn + +PBS must also produce a consolidated `learn` artifact explaining: + +1. globals, +2. lifecycle markers, +3. published wrapper composition, +4. fixed entrypoint protocol, +5. and the relationship between source flow and lowered artifacts. + +## Conformance Matrix + +PBS adopts the following minimum conformance matrix for family `19`. + +### Positive Coverage + +At minimum, one positive fixture must cover: + +1. `declare global` +2. file-level `[Init]` +3. project-level `[Init]` +4. `[Frame]` + +That fixture must provide evidence for: + +1. accepted globals and ordering, +2. generated wrapper publication, +3. `func_id = 0`, +4. `FRAME_RET` in the wrapper path, +5. and hidden boot guard presence. + +### Negative Frontend Coverage + +At minimum, negative frontend coverage must include: + +1. `global` using `fn` in its initializer +2. `global` using `if` in its initializer +3. cycle between globals +4. symbol collision between imported and visible `const` / `global` / `service` / `fn` +5. invalid `[Init]` signature +6. invalid `[Frame]` signature +7. multiple `[Frame]` +8. multiple project init candidates +9. project init outside the `[Frame]` file +10. host call during init without `[InitAllowed]` +11. invalid `[InitAllowed]` target + +### Negative Lowering Coverage + +At minimum, negative lowering coverage must include: + +1. missing published wrapper +2. published wrapper outside physical index `0` +3. missing hidden boot guard +4. missing synthetic origin metadata + +### Runtime Integration Coverage + +At minimum, runtime integration coverage must include: + +1. artifact boot through physical entrypoint `0` +2. evidence that runtime boot no longer depends on nominal export resolution +3. coherent fail-fast reporting for module init failure +4. coherent fail-fast reporting for project init failure + +## Rationale + +This decision intentionally turns the last umbrella stage of topic `19` into an execution gate rather than another semantic layer. + +That matters because the line is already architecturally closed. +What remained was the discipline required to make implementation safe: + +- explicit diagnostics, +- explicit propagation ownership, +- explicit cross-domain runtime ownership, +- and explicit conformance evidence. + +Without this consolidation step, execution work would still have room to drift across specs, runtime, and compiler validation. + +## Invariants + +1. Family `19` diagnostics remain partitioned by phase. +2. Family `19` propagation remains explicit across PBS specs, general specs, runtime, and `learn`. +3. Runtime entrypoint-protocol work remains a named cross-domain dependency rather than an implicit follow-up. +4. Family `19` is not considered implementation-ready without the declared conformance matrix. + +## Explicit Non-Decisions + +1. This decision does not redefine globals surface semantics. +2. This decision does not redefine lifecycle marker semantics. +3. This decision does not redefine published wrapper ownership. +4. This decision does not redefine lowering structure. +5. This decision does not replace the runtime-domain decision work required outside the PBS domain. + +## Execution Readiness + +With this decision accepted, family `19` is considered ready to move into `pull-request/plan` decomposition for: + +1. spec propagation, +2. compiler implementation, +3. runtime cross-domain coordination, +4. diagnostics integration, +5. and conformance fixture execution. diff --git a/docs/compiler/pbs/decisions/Globals and Lifecycle Lowering to IRBackend and IRVM Decision.md b/docs/compiler/pbs/decisions/Globals and Lifecycle Lowering to IRBackend and IRVM Decision.md new file mode 100644 index 00000000..283a032f --- /dev/null +++ b/docs/compiler/pbs/decisions/Globals and Lifecycle Lowering to IRBackend and IRVM Decision.md @@ -0,0 +1,194 @@ +# Globals and Lifecycle Lowering to IRBackend and IRVM Decision + +Status: Accepted +Date: 2026-03-22 +Related Agenda: `docs/compiler/pbs/agendas/19.4. Globals and Lifecycle Lowering to IRBackend/IRVM Agenda.md` + +## Context + +After closing globals, lifecycle markers, and published wrapper ownership, PBS v1 still needed a precise lowering contract for how those decisions appear in executable compiler artifacts. + +The remaining problem was not semantic policy anymore. +It was structural representation: + +- where globals become explicit, +- how synthetic lifecycle callables are represented, +- how one-shot boot state is materialized, +- how diagnostics and attribution survive synthetic lowering, +- and what minimum backend shape must be preserved before `IRVM`. + +Important fixed inputs already existed: + +- runtime globals are part of the PBS source model, +- module init and project init are semantically defined, +- the published wrapper is the physical entrypoint, +- `FRAME_RET` belongs to that wrapper, +- and VM-level global access already exists as `GET_GLOBAL` / `SET_GLOBAL`. + +## Decision + +PBS adopts the following lowering policy in v1: + +1. Globals must become explicit structural entities at the `IRBackend` boundary. +2. Globals must not be deferred to an implicit late materialization below that boundary. +3. The lowering pipeline must represent synthetic lifecycle artifacts explicitly as synthetic callables rather than ad hoc emitted fragments. +4. The following synthetic callable classes are mandatory: + - `FILE_INIT_FRAGMENT` + - `MODULE_INIT` + - `PROJECT_INIT` + - `PUBLISHED_FRAME_WRAPPER` +5. The wrapper published as the physical entrypoint must exist explicitly in the lowered graph. +6. The one-shot boot guard must exist explicitly as a hidden global. +7. That hidden global is compiler-owned internal state and is not user-visible. +8. The lowering path must target the already-existing VM global operations: + - `GET_GLOBAL` + - `SET_GLOBAL` + +## IRBackend Shape + +PBS adopts the following minimum structural shape for `IRBackend`-level representation. + +### Globals + +Each backend global must preserve, at minimum: + +1. `name` +2. `ownerModuleId` +3. `type` +4. `slot` +5. `visibility` +6. `isHidden` +7. `origin` + +This applies both to: + +- user-authored globals, +- and compiler-generated hidden globals such as the boot guard. + +### Callables + +The backend must distinguish explicitly between: + +1. ordinary userland callables, +2. synthetic compiler-generated callables. + +Synthetic callables must carry stable class identity rather than being inferred from naming convention alone. + +### Hidden Global Kind + +The hidden boot guard must carry explicit structural identity: + +1. `BOOT_GUARD` + +It must not be modeled merely as an informal hidden symbol name. + +## Attribution and Diagnostics + +PBS adopts the following attribution policy for synthetic lowering: + +1. Synthetic globals and synthetic callables must carry origin metadata sufficient for remapping errors to real userland code where possible. +2. Synthetic origin metadata must preserve, at minimum: + - `derivedFromFile` + - `derivedFromModule` + - `derivedFromUserSymbol` + - `primarySpan` + - `fallbackSyntheticLabel` +3. When an error originates from synthetic lowering but has a defensible real userland origin, diagnostics must prefer the real userland span. +4. Purely synthetic spans should be shown only when no defensible userland origin exists. + +## Synthetic Callable Policy + +PBS adopts the following architectural rule: + +1. Synthetic callables are first-class lowering artifacts. +2. They are not incidental codegen accidents. +3. Their explicit class identity exists to support: + - deterministic ordering, + - attribution, + - debug and tooling, + - conformance tests, + - and future lifecycle extensions without reopening the lowering model. + +## Hidden Boot Guard Policy + +PBS adopts the following policy for the boot guard: + +1. It exists as a hidden program-owned global. +2. Userland cannot name it. +3. Userland cannot read it. +4. Userland cannot mutate it. +5. Its sole role is to enforce one-shot bootstrap semantics in the physical wrapper. + +## Rationale + +This decision intentionally chooses an explicit backend shape over implicit late-stage magic. + +That matters because: + +- globals are now part of the language contract, +- lifecycle artifacts now exist as semantically meaningful structure, +- diagnostics must remain attributable to real source even after synthesis, +- and backend conformance becomes much harder if the representation boundary stays implicit. + +The chosen model also creates a stable editorial split: + +- specs explain the structure normatively, +- and `learn` explains the composition through real source examples. + +## Structural Diagnostics and Validation + +PBS must provide, at minimum, the following structural checks or equivalent validation evidence: + +1. `synthetic wrapper entrypoint missing` +2. `published entrypoint is not function index 0` +3. `hidden boot guard is missing` +4. `synthetic callable origin missing` + +These may be implemented as backend diagnostics, validation failures, or conformance assertions, as long as the invariant remains enforced and observable. + +## Invariants + +1. Globals are explicit at the `IRBackend` boundary. +2. Synthetic lifecycle callables are explicit at the `IRBackend` boundary. +3. Hidden compiler state remains distinguishable from user state. +4. Synthetic lowering must preserve enough origin metadata for defensible remapping. +5. The lowering path to `IRVM` must preserve the previously accepted wrapper and entrypoint protocol. + +## Explicit Non-Decisions + +1. This decision does not redefine source syntax. +2. This decision does not redefine lifecycle semantics. +3. This decision does not redefine manifest publication. +4. This decision does not freeze one concrete implementation class hierarchy. + +## Spec and Learn Impact + +This decision should feed at least: + +1. `docs/compiler/pbs/specs/13. Lowering IRBackend Specification.md` +2. relevant general lowering specs outside the PBS domain, when they need the new explicit shape +3. `docs/compiler/pbs/specs/12. Diagnostics Specification.md` + +It also requires didactic propagation to PBS `learn`, where the model should be explained with source-level examples showing how: + +1. `declare global` +2. file `[Init]` +3. project `[Init]` +4. and `[Frame]` + +compose into synthetic lowered artifacts and the published wrapper. + +## Validation Notes + +At minimum, validation for this decision should include: + +1. a fixture combining globals, file init, project init, and frame; +2. evidence of generated: + - file init fragment, + - module init, + - project init, + - published wrapper, + - hidden boot guard; +3. evidence that the wrapper occupies `func_id = 0`; +4. evidence that `FRAME_RET` lives in the wrapper path; +5. evidence that a synthetic-lowering error remaps to real userland span when a defensible origin exists.