prometeu-studio/docs/compiler/pbs/decisions/Globals and Lifecycle Lowering to IRBackend and IRVM Decision.md

195 lines
6.8 KiB
Markdown

# 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.