Merge pull request 'implements PLN-0127' (#21) from dev/multi-frontend-sdk-canonical-definition 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: 648
Intrepid/Prometeu/Studio/pipeline/head This commit looks good

Reviewed-on: #21
This commit is contained in:
bquarkz 2026-09-19 01:39:18 +00:00
commit d0b91f8526
7 changed files with 343 additions and 123 deletions

View File

@ -1,9 +1,9 @@
{"type":"meta","next_id":{"DSC":66,"AGD":69,"DEC":48,"PLN":127,"LSN":64,"CLSN":1}} {"type":"meta","next_id":{"DSC":66,"AGD":69,"DEC":49,"PLN":128,"LSN":65,"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":"done","ticket":"multi-frontend-sdk-canonical-definition","title":"Auditoria e centralizacao gradual da definicao canonica do SDK","created_at":"2026-07-15","updated_at":"2026-09-19","tags":["compiler","compiler-general","sdk","stdlib","hostcalls","intrinsics","multi-frontend"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0064","file":"discussion/lessons/DSC-0061-multi-frontend-sdk-canonical-definition/LSN-0064-runtime-owns-console-abi-pbs-is-delivery.md","status":"done","created_at":"2026-09-19","updated_at":"2026-09-19"}]}
{"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-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"}]}

View File

@ -0,0 +1,121 @@
---
id: LSN-0064
ticket: multi-frontend-sdk-canonical-definition
title: Runtime owns console ABI; PBS is delivery
created: 2026-09-19
tags: [compiler, compiler-general, sdk, stdlib, hostcalls, intrinsics, multi-frontend]
---
# Runtime owns console ABI; PBS is delivery
## Original Problem
"SDK" mixed three layers: platform ABI, PBS stdlib shells, and docs. The PBS
compiler reads `[Host]` and `[IntrinsicCall]` from `.pbs` files. It does not
read the runtime registry. Intrinsics already had a CSV in the runtime
repository, a handwritten Java enum, and a disabled parity test. Spec 8
documented `audio` and `@core:math`. Disk had `game/stdlib/1` with `color`,
`asset`, `composer`, `gfx`, `input`, and `log`. Spec 18 preferred `@sdk:*` for
host APIs while `@sdk:input` was a builtin.
There is no second language in this phase. The risk was not a missing generic
SDK. The risk was treating PBS shells, or a stale spec, as console ABI.
DEC-0047 had already classified canonical host identity as platform-owned and
left `PbsHostAdmissionValidator` in the PBS package until a shared source
existed.
## Consolidated Decision
This discussion was an audit. It published an authority map. It did not create
a canonical schema, generate bindings, enable intrinsic parity, or move the
host-admission validator.
The console has two distinct axes:
- VM-owned intrinsics, identity `canonical_name@version` plus `final_id`;
- host-backed calls, identity `(module, name, version)` plus capability.
Do not unify those axes into one catalog while PBS is the only frontend.
Conflict resolution:
- Intrinsic conflict: `runtime/docs/vm-arch/INTRINSICS.csv` wins. Studio
`docs/vm-arch/INTRINSICS.csv` is a mirror. `IRVMIntrinsicDefinition` is
derived. PBS `[BuiltinType]` / `[IntrinsicCall]` shells are delivery.
- Host conflict: runtime spec 16 and `SyscallMeta` win. PBS `[Host]` attributes
must not define ABI. They declare the shell the PBS compiler reads today.
`@sdk:*` / `@core:*` paths must not imply ownership. `@sdk:input` is a
registered builtin exception. It was not moved to `@core`.
PBS conformance means PBS shells and docs match runtime ABI, not the reverse.
`PbsHostAdmissionValidator` may stay in the PBS package. `E_HOST_*` is not
eternal PBS semantics.
## Final Implementation
The work was editorial and test-facing.
Spec 18 now states that PBS stdlib is delivery and must not define syscall IDs,
intrinsic `final_id` values, or `SyscallMeta`. Runtime catalogs outrank it.
`@sdk:input` is recorded as the current builtin exception.
Spec 8 now documents `<target>/stdlib/<N>/...` with current line `1` at
`game/stdlib/1`: `core/color` and `sdk/{asset,composer,gfx,input,log}`. It no
longer ships `audio` or `@core:math` as current modules.
Spec 6.2 now requires PBS host shells to repeat the runtime registry and forbids
inventing `(module, name, version)`. The authority example is
`("gfx2d", "clear", 1)`.
`ConsoleAbiAuthoritySpecTest` locks those sentences. No production compiler
code, stdlib `.pbs`, or validator package moved. The intrinsic parity test
stays disabled.
## Examples
Runtime wins:
- `color.rgb@1` / `final_id` `0x1101` come from `INTRINSICS.csv`;
- `("gfx2d", "clear", 1)` and `("asset", "load", 1)` come from `SyscallMeta`.
PBS delivers, and does not own, those identities:
- `@core:color` with `[BuiltinType(name = "color", version = 1)]`;
- `@sdk:gfx` `LowGfx.clear` with `[Host(module = "gfx2d", name = "clear", version = 1)]`;
- `@sdk:input` with `[BuiltinType]` / `[IntrinsicCall]` under `@sdk`.
Stale docs that the recut removed as current line-1 inventory:
- `stdlib/1/sdk/audio`;
- `@core:math` as a packaged module.
## Pitfalls
- Do not treat PBS stdlib as the ABI catalog because the compiler already reads
it. That is convenience, not authority.
- Do not create `HOSTCALLS.csv` or generate the Java enum because the map now
exists. A catalog waits on a second consumer.
- Do not move `PbsHostAdmissionValidator` on the strength of this map. DEC-0047
classified identity as platform; this discussion published who wins; the
validator still has no shared catalog to consume.
- Do not read `@sdk` as host and `@core` as VM. Path is packaging. `@sdk:input`
is builtin.
- Do not enable `IRVMIntrinsicRegistryParityTest` as a side effect of a doc
recut. That is compiler/runtime sync, not PBS packaging conformance.
- Do not put the authority map only in a decision. Housekeep deletes workflow
artifacts. Specs and this lesson keep the map.
## References
- Decision: `DEC-0048`
- Plan: `PLN-0127`
- Related lesson: `LSN-0063` - Language vs platform validation ownership
- Related lesson: `LSN-0061` - PBX is the language-neutral runtime boundary
- `docs/specs/compiler/18. Standard Library Surface Specification.md`
- `docs/specs/compiler-languages/pbs/8. Stdlib Environment Packaging and Loading Specification.md`
- `docs/specs/compiler-languages/pbs/6.2. Host ABI Binding and Loader Resolution Specification.md`
- `docs/vm-arch/README.md`
- `../runtime/docs/vm-arch/INTRINSICS.csv`
- `../runtime/docs/specs/runtime/16-host-abi-and-syscalls.md`
- `prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/specs/ConsoleAbiAuthoritySpecTest.java`

View File

@ -1,78 +0,0 @@
---
id: AGD-0064
ticket: multi-frontend-sdk-canonical-definition
title: Auditoria e centralizacao gradual da definicao canonica do SDK
status: open
created: 2026-07-15
resolved:
decision:
tags: [compiler, compiler-general, sdk, stdlib, hostcalls, intrinsics, multi-frontend]
---
# Agenda - Centralizar a definicao do SDK
## Objetivo
Domain owner: `compiler/general`, com referencias a `compiler/pbs` e `vm-arch`.
Auditar onde hostcalls, intrinsics, tipos fundamentais e APIs do console sao definidos hoje antes de propor uma fonte canonica do SDK.
## Contexto atual
Existem specs em `docs/vm-arch/INTRINSICS.csv`, docs de stdlib em `docs/specs/compiler/18. Standard Library Surface Specification.md`, specs PBS de stdlib e host ABI, alem de possiveis registries em codigo e fixtures.
## Escopo
- Mapear fontes atuais da verdade.
- Identificar definicoes geradas, duplicadas e manuais.
- Propor caminho gradual para um schema canonico.
## Fora de escopo
- Migracao grande do SDK.
- Gerar bindings para C#, Kotlin, TypeScript ou outras linguagens.
- Escolher formato definitivo antes da auditoria.
## Arquivos e componentes a inspecionar
- `docs/vm-arch/INTRINSICS.csv`
- `docs/specs/compiler/18. Standard Library Surface Specification.md`
- `docs/specs/compiler-languages/pbs/5. Manifest, Stdlib, and SDK Resolution Specification.md`
- `docs/specs/compiler-languages/pbs/6.1. Intrinsics and Builtin Types Specification.md`
- `prometeu-compiler/...` registries de hostcalls/intrinsics/stdlib
- runtime/PVM quando presente no workspace ou submodulos relacionados
## Alteracoes propostas
Opcao A: agenda de auditoria pura, produzindo mapa de fontes e duplicacoes.
Opcao B: criar schema canonico minimo depois da auditoria, sem migrar todos os consumidores.
Recomendacao inicial: primeiro fechar auditoria; so uma decision posterior deve escolher formato e migracao.
## Estrategia de implementacao
Listar cada hostcall/intrinsic/tipo fundamental em suas fontes atuais, comparar assinatura, capability, versao e docs, e classificar divergencias.
## Testes necessarios
- Testes de paridade entre registry runtime/backend e specs existentes, se ja houver fonte estruturada.
- Testes de nao divergencia para IDs e assinaturas apos qualquer centralizacao.
## Criterios de aceitacao
- Existe mapa claro de fonte real da verdade.
- Duplicacoes e divergencias ficam registradas.
- Nenhuma migracao ampla e iniciada sem nova decisao.
## Riscos
- Tratar docs como fonte real quando o codigo ja diverge.
- Iniciar geracao antes de saber quem consome cada definicao.
## Decisoes que devem ser registradas
- Fonte canonica proposta.
- Campos obrigatorios do SDK.
- Sequencia de migracao segura.

View File

@ -15,6 +15,10 @@ This document defines the current contract between:
Its purpose is to let compiler and runtime work in parallel without diverging on the most critical boundary: Its purpose is to let compiler and runtime work in parallel without diverging on the most critical boundary:
how host-backed SDK calls become load-time-resolved numeric syscalls. how host-backed SDK calls become load-time-resolved numeric syscalls.
PBS `declare host` / `[Host]` shells are compile-time delivery. The
loader-facing catalog is runtime-owned. This document MUST NOT publish syscall
IDs or `SyscallMeta`.
This document is intentionally narrower than a full PBX or VM specification. This document is intentionally narrower than a full PBX or VM specification.
It focuses on loader behavior and the minimum artifact contract the loader must consume. It focuses on loader behavior and the minimum artifact contract the loader must consume.
@ -44,16 +48,20 @@ This document does not define:
This document follows two prior decisions: This document follows two prior decisions:
1. Canonical host identity is defined by the hardware ABI as `(module, name, version)`. 1. Canonical host identity is defined by the runtime host registry as `(module, name, version)`.
2. User code does not declare host bindings directly; SDK/toolchain-controlled modules expose reserved `declare host` surfaces and the compiler lowers those usages into PBX host-binding metadata. 2. User code does not declare host bindings directly; SDK/toolchain-controlled modules expose reserved `declare host` surfaces and the compiler lowers those usages into PBX host-binding metadata.
PBS shells MUST repeat identities already published by the runtime registry
(`../runtime/docs/specs/runtime/16-host-abi-and-syscalls.md` and `SyscallMeta`).
They MUST NOT invent `(module, name, version)`.
This document therefore treats: This document therefore treats:
- `declare host Gfx { fn draw_pixel(...); }` - `declare host LowGfx { [Host(module = "gfx2d", name = "clear", version = 1)] fn clear(...); }`
as compile-time surface only, and treats: as compile-time surface only, and treats:
- `("gfx", "draw_pixel", 1)` - `("gfx2d", "clear", 1)`
as the normative runtime-facing identity. as the normative runtime-facing identity.
@ -63,7 +71,7 @@ The host-binding pipeline is:
1. User code imports SDK surfaces such as `Gfx` from `@sdk:gfx` and `Composer` from `@sdk:composer`. 1. User code imports SDK surfaces such as `Gfx` from `@sdk:gfx` and `Composer` from `@sdk:composer`.
2. The compiler resolves those surfaces against the selected stdlib line. 2. The compiler resolves those surfaces against the selected stdlib line.
3. The compiler maps each host-backed SDK member to a canonical identity `(module, name, version)`. 3. The compiler maps each host-backed SDK member to a canonical identity `(module, name, version)` that already exists in the runtime host registry.
4. The compiler emits those required canonical identities into the PBX `SYSC` table. 4. The compiler emits those required canonical identities into the PBX `SYSC` table.
5. The compiler emits pre-load host call sites as `HOSTCALL <sysc_index>`. 5. The compiler emits pre-load host call sites as `HOSTCALL <sysc_index>`.
6. At cartridge load time, the loader resolves `SYSC` entries against the host syscall registry. 6. At cartridge load time, the loader resolves `SYSC` entries against the host syscall registry.
@ -84,7 +92,7 @@ Every host binding is identified by the triple:
Rules: Rules:
- `module` is the canonical host subsystem namespace, such as `gfx` or `audio`. - `module` is the canonical host subsystem namespace, such as `gfx2d` or `asset`.
- `name` is the canonical host operation name within that module. - `name` is the canonical host operation name within that module.
- `version` is the canonical ABI version of that host operation. - `version` is the canonical ABI version of that host operation.
- This identity is stable across source languages and SDK naming styles. - This identity is stable across source languages and SDK naming styles.
@ -310,7 +318,10 @@ Rules:
- the loader resolves only against this canonical registry, - the loader resolves only against this canonical registry,
- unknown identities are load errors, - unknown identities are load errors,
- successful resolution yields numeric syscall identifiers and associated metadata, - successful resolution yields numeric syscall identifiers and associated metadata,
- the resolved metadata is authoritative for capability gating and later runtime verification. - the resolved metadata is authoritative for capability gating and later runtime verification,
- PBS `declare host` / `[Host]` shells MUST repeat identities from this registry,
- PBS shells MUST NOT invent `(module, name, version)`,
- this specification MUST NOT publish the syscall catalog; runtime spec 16 and `SyscallMeta` do.
For the current asset runtime surface, the canonical registry entries include: For the current asset runtime surface, the canonical registry entries include:

View File

@ -16,7 +16,11 @@ Its purpose is to make the stdlib:
This document complements the normative language-level model in: This document complements the normative language-level model in:
- [5. Manifest, Stdlib, and SDK Resolution Specification.md](/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/docs/specs/pbs/5.%20Manifest,%20Stdlib,%20and%20SDK%20Resolution%20Specification.md) - [5. Manifest, Stdlib, and SDK Resolution Specification.md](5.%20Manifest%2C%20Stdlib%2C%20and%20SDK%20Resolution%20Specification.md)
This document is PBS packaging. It MUST NOT define console ABI. Intrinsic
`final_id` values and host `SyscallMeta` remain runtime-owned. Physical stdlib
path MUST NOT imply VM-owned versus host-backed ownership.
## 2. Scope ## 2. Scope
@ -53,52 +57,66 @@ The recommended Studio layout is:
```text ```text
prometeu-compiler/frontends/prometeu-frontend-pbs/ prometeu-compiler/frontends/prometeu-frontend-pbs/
src/main/resources/ src/main/resources/
stdlib/ <target>/
1/ stdlib/
sdk/ 1/
composer/ core/
main.pbs color/
mod.barrel main.pbs
gfx/ mod.barrel
main.pbs sdk/
mod.barrel asset/
asset/ main.pbs
main.pbs mod.barrel
mod.barrel composer/
audio/ main.pbs
main.pbs mod.barrel
mod.barrel gfx/
core/ main.pbs
math/ mod.barrel
main.pbs input/
mod.barrel main.pbs
mod.barrel
log/
main.pbs
mod.barrel
``` ```
Interpretation: Interpretation:
- `stdlib/1` selects stdlib major line `1`, - `<target>` is the `AppMode` export name (`game` for the current line-1 environment),
- `game/stdlib/1` selects stdlib major line `1` for that target,
- `sdk` and `core` are reserved project spaces, - `sdk` and `core` are reserved project spaces,
- `composer`, `gfx`, `audio`, `math` are module paths within those reserved spaces, - current line `1` modules are `color`, `asset`, `composer`, `gfx`, `input`, and `log`,
- `main.pbs` and `mod.barrel` form the interface module contents. - `main.pbs` and `mod.barrel` form the interface module contents.
Current line `1` MUST NOT be documented as shipping `audio` or `@core:math`.
Those names are not packaged in the current environment. `@sdk:input` is a
VM-owned builtin shell; its path does not make it host-backed.
## 5. Logical Mapping ## 5. Logical Mapping
The compiler must treat the physical layout as a logical stdlib environment. The compiler must treat the physical layout as a logical stdlib environment.
Required mapping: Required mapping:
- `stdlib/<N>/sdk/gfx` -> `@sdk:gfx` - `<target>/stdlib/<N>/<space>/<module>` -> `@<space>:<module>`
- `stdlib/<N>/sdk/composer` -> `@sdk:composer`
- `stdlib/<N>/sdk/asset` -> `@sdk:asset` Current line `1` (`game`) mapping:
- `stdlib/<N>/sdk/audio` -> `@sdk:audio`
- `stdlib/<N>/core/math` -> `@core:math` - `game/stdlib/1/core/color` -> `@core:color`
- `stdlib/<N>/core/math/vector` -> `@core:math/vector` - `game/stdlib/1/sdk/asset` -> `@sdk:asset`
- `game/stdlib/1/sdk/composer` -> `@sdk:composer`
- `game/stdlib/1/sdk/gfx` -> `@sdk:gfx`
- `game/stdlib/1/sdk/input` -> `@sdk:input`
- `game/stdlib/1/sdk/log` -> `@sdk:log`
Rules: Rules:
- physical storage is an implementation detail, - physical storage is an implementation detail,
- logical module identity is authoritative, - logical module identity is authoritative,
- callers of the resolver should work with logical addresses such as `@sdk:gfx` and `@sdk:composer`, not resource paths. - callers of the resolver should work with logical addresses such as `@sdk:gfx` and `@core:color`, not resource paths,
- physical path MUST NOT imply VM-owned versus host-backed ownership.
## 6. Module File Convention ## 6. Module File Convention
@ -150,7 +168,8 @@ Minimum operations:
- `resolve(@sdk:gfx)` - `resolve(@sdk:gfx)`
- `resolve(@sdk:composer)` - `resolve(@sdk:composer)`
- `resolve(@core:math/vector)` - `resolve(@sdk:input)`
- `resolve(@core:color)`
### 7.3 `StdlibModuleSource` ### 7.3 `StdlibModuleSource`

View File

@ -7,6 +7,9 @@ Applies to: normative stdlib-facing API surface, reserved stdlib project spaces,
This document will define the normative user-facing standard-library surface for PBS. This document will define the normative user-facing standard-library surface for PBS.
This document is PBS delivery. It does not own console ABI. Intrinsic
`final_id` values and host syscall metadata are runtime-owned.
## 2. Scope ## 2. Scope
This document is intended to define: This document is intended to define:
@ -28,15 +31,22 @@ This document does not define:
Normative precedence: Normative precedence:
1. `5. Manifest, Stdlib, and SDK Resolution Specification.md` 1. Runtime intrinsic catalog (`../runtime/docs/vm-arch/INTRINSICS.csv`; Studio mirror `docs/vm-arch/INTRINSICS.csv`)
2. `8. Stdlib Environment Packaging and Loading Specification.md` 2. Runtime host ABI (`../runtime/docs/specs/runtime/16-host-abi-and-syscalls.md` and `SyscallMeta`)
3. `6. VM-owned vs Host-backed.md` 3. `5. Manifest, Stdlib, and SDK Resolution Specification.md`
4. `6.1. Intrinsics and Builtin Types Specification.md` 4. `8. Stdlib Environment Packaging and Loading Specification.md`
5. `6.2. Host ABI Binding and Loader Resolution Specification.md` 5. `6. VM-owned vs Host-backed.md`
6. This document 6. `6.1. Intrinsics and Builtin Types Specification.md`
7. `6.2. Host ABI Binding and Loader Resolution Specification.md`
8. This document
If a rule here conflicts with higher-precedence specs, it is invalid. If a rule here conflicts with higher-precedence specs, it is invalid.
This document MUST NOT define numeric syscall identifiers, intrinsic `final_id`
values, or `SyscallMeta`. PBS `[Host]` and `[IntrinsicCall]` attributes MUST
repeat identities already published by those runtime catalogs. They MUST NOT
invent console ABI.
## 4. Normative Inputs ## 4. Normative Inputs
This document depends on, at minimum: This document depends on, at minimum:
@ -57,6 +67,9 @@ The following inputs are already fixed elsewhere and must not be contradicted he
- User code must import stdlib modules explicitly. - User code must import stdlib modules explicitly.
- Canonical host identity comes from reserved host-binding metadata, not from source owner spelling. - Canonical host identity comes from reserved host-binding metadata, not from source owner spelling.
- VM-owned builtin type, builtin constant, and intrinsic surfaces may be exposed through reserved stdlib shells without transferring semantic ownership away from the VM. - VM-owned builtin type, builtin constant, and intrinsic surfaces may be exposed through reserved stdlib shells without transferring semantic ownership away from the VM.
- Console ABI authority is runtime-owned. PBS stdlib is delivery.
- Reserved project-space path (`@sdk:*` / `@core:*`) MUST NOT imply VM-owned versus host-backed ownership.
- Current stdlib line `1` ships a VM-owned builtin input shell at `@sdk:input`. That exception does not make `@sdk:*` the VM-owned space.
## 6. Initial Section Targets ## 6. Initial Section Targets
@ -78,7 +91,10 @@ The following items remain to be closed in future agenda discussion.
- Whether `@core:*` is specified as language-adjacent utility surface or as ordinary stdlib contract. - Whether `@core:*` is specified as language-adjacent utility surface or as ordinary stdlib contract.
- How stdlib API evolution is documented and conformance-tested. - How stdlib API evolution is documented and conformance-tested.
- Whether some interface modules remain toolchain-private and outside user-facing stdlib surface. - Whether some interface modules remain toolchain-private and outside user-facing stdlib surface.
- Whether builtin shells may appear in `@sdk:*` as well as `@core:*`, or whether `@sdk:*` should remain host-facing only by policy.
Settled by DEC-0048 and not reopened here:
- Builtin shells MAY appear in `@sdk:*` as well as `@core:*`. Path MUST NOT imply ownership. Current line `1` exception: `@sdk:input`.
## 8. Non-Goals ## 8. Non-Goals
@ -127,6 +143,12 @@ Rules:
- but ownership remains governed by the VM-owned vs host-backed classification, - but ownership remains governed by the VM-owned vs host-backed classification,
- and placing a builtin shell in stdlib does not make it host-backed. - and placing a builtin shell in stdlib does not make it host-backed.
Current line `1` exception:
- `@sdk:input` exposes VM-owned builtin input types through `[BuiltinType]` and `[IntrinsicCall]`.
- that module is not host-backed.
- the `@sdk:*` preference for host-backed APIs still holds for new host modules.
## 11. Builtin Shell Surfaces ## 11. Builtin Shell Surfaces
Reserved stdlib modules may expose builtin declarations as compile-time-only Reserved stdlib modules may expose builtin declarations as compile-time-only
@ -205,6 +227,10 @@ Their canonical runtime-facing identities still come from builtin metadata such
as `BuiltinType(name="vec2", version=1)` and as `BuiltinType(name="vec2", version=1)` and
`BuiltinConst(target="vec2", name="zero", version=1)`. `BuiltinConst(target="vec2", name="zero", version=1)`.
Current stdlib line `1` ships `Color` at `@core:color`. The `@core:math` import
above is an identity illustration, not a claim that `@core:math` is packaged in
line `1`.
## 14. Deterministic Stdlib Surface Failures ## 14. Deterministic Stdlib Surface Failures
At minimum, a conforming implementation must reject: At minimum, a conforming implementation must reject:
@ -214,3 +240,15 @@ At minimum, a conforming implementation must reject:
3. a user-facing stdlib module that exports executable PBS bodies for builtin semantics, 3. a user-facing stdlib module that exports executable PBS bodies for builtin semantics,
4. a stdlib line that exposes conflicting canonical builtin identities through the same resolved environment, 4. a stdlib line that exposes conflicting canonical builtin identities through the same resolved environment,
5. a stdlib line that exposes conflicting canonical host identities through the same resolved environment. 5. a stdlib line that exposes conflicting canonical host identities through the same resolved environment.
## 15. Console ABI Non-Ownership
This specification MUST NOT:
1. define numeric syscall identifiers,
2. define intrinsic `final_id` values,
3. publish `SyscallMeta`,
4. or treat PBS `[Host]` / `[IntrinsicCall]` attributes as the ABI catalog.
PBS shells MUST repeat identities already published by the runtime catalogs
named in section 3.

View File

@ -0,0 +1,109 @@
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 static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
class ConsoleAbiAuthoritySpecTest {
private static final String SPEC_18 =
"docs/specs/compiler/18. Standard Library Surface Specification.md";
private static final String PBS_SPEC_8 =
"docs/specs/compiler-languages/pbs/8. Stdlib Environment Packaging and Loading Specification.md";
private static final String PBS_SPEC_6_2 =
"docs/specs/compiler-languages/pbs/6.2. Host ABI Binding and Loader Resolution Specification.md";
@Test
void spec18MustTreatStdlibAsDeliveryAndMustNotOwnConsoleAbi() throws IOException {
final var content = Files.readString(locateRepoRoot().resolve(SPEC_18));
assertTrue(
content.contains("This document is PBS delivery. It does not own console ABI."),
"spec 18 must state that PBS stdlib is delivery, not console ABI");
assertTrue(
content.contains("This document MUST NOT define numeric syscall identifiers, intrinsic `final_id`"),
"spec 18 must forbid defining syscall IDs and intrinsic final IDs");
assertTrue(
content.contains("or `SyscallMeta`"),
"spec 18 must forbid publishing SyscallMeta");
assertTrue(
content.contains("## 15. Console ABI Non-Ownership"),
"spec 18 must contain Console ABI Non-Ownership");
assertTrue(
content.contains("Reserved project-space path (`@sdk:*` / `@core:*`) MUST NOT imply VM-owned versus host-backed ownership."),
"spec 18 must state that @sdk/@core paths do not imply ownership");
assertTrue(
content.contains("Current stdlib line `1` ships a VM-owned builtin input shell at `@sdk:input`."),
"spec 18 must record @sdk:input as the current builtin exception");
}
@Test
void spec8MustDocumentCurrentGameStdlibLayout() throws IOException {
final var content = Files.readString(locateRepoRoot().resolve(PBS_SPEC_8));
final var layoutFence = extractFirstTextFence(content);
assertTrue(content.contains("game/stdlib/1"), "spec 8 must document game/stdlib/1");
assertTrue(content.contains("game/stdlib/1/core/color"), "spec 8 must map @core:color");
assertTrue(content.contains("game/stdlib/1/sdk/input"), "spec 8 must map @sdk:input");
assertTrue(content.contains("game/stdlib/1/sdk/log"), "spec 8 must map @sdk:log");
assertTrue(
content.contains("Physical stdlib\npath MUST NOT imply VM-owned versus host-backed ownership."),
"spec 8 must state that packaging path does not imply ownership");
assertTrue(layoutFence.contains("core/\n color/"), "layout fence must include core/color");
assertTrue(layoutFence.contains("input/"), "layout fence must include sdk/input");
assertTrue(layoutFence.contains("log/"), "layout fence must include sdk/log");
assertFalse(layoutFence.contains("audio/"), "layout fence must not ship audio as a current module");
assertFalse(layoutFence.contains("math/"), "layout fence must not ship core/math as a current module");
}
@Test
void spec62MustRequirePbsHostShellsToRepeatRuntimeRegistry() throws IOException {
final var content = Files.readString(locateRepoRoot().resolve(PBS_SPEC_6_2));
assertTrue(
content.contains("PBS shells MUST repeat identities already published by the runtime registry"),
"spec 6.2 must require PBS shells to repeat the runtime registry");
assertTrue(
content.contains("They MUST NOT invent `(module, name, version)`."),
"spec 6.2 must forbid inventing canonical host identity");
assertTrue(
content.contains("This document MUST NOT publish syscall\nIDs or `SyscallMeta`."),
"spec 6.2 must not publish the syscall catalog");
assertTrue(
content.contains("(\"gfx2d\", \"clear\", 1)"),
"spec 6.2 authority example must use a current runtime identity");
}
private static String extractFirstTextFence(final String content) {
final var startToken = "```text";
final var start = content.indexOf(startToken);
if (start < 0) {
fail("spec 8 must contain a text layout fence");
}
final var fenceStart = start + startToken.length();
final var end = content.indexOf("```", fenceStart);
if (end < 0) {
fail("spec 8 layout fence is unclosed");
}
return content.substring(fenceStart, end);
}
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");
}
}