implements PLN-0127
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: 648
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: 648
Publish the console ABI authority map: runtime catalogs win, PBS stdlib is delivery. Recut specs 18, 8, and 6.2 and lock them with ConsoleAbiAuthoritySpecTest. Housekeep DSC-0061 with LSN-0064.
This commit is contained in:
parent
4d8dcf28bb
commit
2b881f5a76
@ -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"}]}
|
||||||
|
|||||||
@ -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`
|
||||||
@ -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.
|
|
||||||
|
|
||||||
@ -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:
|
||||||
|
|
||||||
|
|||||||
@ -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/
|
||||||
|
<target>/
|
||||||
stdlib/
|
stdlib/
|
||||||
1/
|
1/
|
||||||
|
core/
|
||||||
|
color/
|
||||||
|
main.pbs
|
||||||
|
mod.barrel
|
||||||
sdk/
|
sdk/
|
||||||
|
asset/
|
||||||
|
main.pbs
|
||||||
|
mod.barrel
|
||||||
composer/
|
composer/
|
||||||
main.pbs
|
main.pbs
|
||||||
mod.barrel
|
mod.barrel
|
||||||
gfx/
|
gfx/
|
||||||
main.pbs
|
main.pbs
|
||||||
mod.barrel
|
mod.barrel
|
||||||
asset/
|
input/
|
||||||
main.pbs
|
main.pbs
|
||||||
mod.barrel
|
mod.barrel
|
||||||
audio/
|
log/
|
||||||
main.pbs
|
|
||||||
mod.barrel
|
|
||||||
core/
|
|
||||||
math/
|
|
||||||
main.pbs
|
main.pbs
|
||||||
mod.barrel
|
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`
|
||||||
|
|
||||||
|
|||||||
@ -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.
|
||||||
|
|||||||
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user