# PBS Stdlib Environment Packaging and Loading Specification

Status: Draft v1 (Temporary)  
Applies to: Studio PBS frontend stdlib packaging, stdlib environment discovery, reserved stdlib project spaces, and compiler-side stdlib loading abstractions

## 1. Purpose

This document defines a practical packaging and loading model for the PBS stdlib environment inside the Studio compiler frontend.

Its purpose is to make the stdlib:

- available to the compiler without hardcoded symbol tables,
- structured as real PBS interface modules,
- versioned by stdlib major line,
- and loadable through explicit compiler abstractions.

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)

## 2. Scope

This document defines:

- the recommended Studio packaging layout for stdlib interface modules,
- the logical mapping between stdlib line, reserved project space, and module path,
- the minimum compiler abstractions required to load stdlib modules,
- the relationship between `resources` packaging and the logical stdlib environment.

This document does not define:

- runtime loader behavior,
- PBX emission,
- registry publication of stdlib packs,
- final external distribution of stdlib outside Studio.

## 3. Core Model

The compiler must load stdlib modules as real interface modules, not as hardcoded built-ins.

Rules:

- the stdlib is selected by the root project's `stdlib` major,
- each stdlib line defines one stdlib environment,
- a stdlib environment exposes reserved project spaces such as `@sdk:*` and `@core:*`,
- each reserved project space contains one or more modules,
- each module is represented as PBS source plus `mod.barrel`.

## 4. Recommended Studio Packaging Layout

The recommended Studio layout is:

```text
prometeu-compiler/frontends/prometeu-frontend-pbs/
  src/main/resources/
    stdlib/
      1/
        sdk/
          composer/
            main.pbs
            mod.barrel
          gfx/
            main.pbs
            mod.barrel
          asset/
            main.pbs
            mod.barrel
          audio/
            main.pbs
            mod.barrel
        core/
          math/
            main.pbs
            mod.barrel
```

Interpretation:

- `stdlib/1` selects stdlib major line `1`,
- `sdk` and `core` are reserved project spaces,
- `composer`, `gfx`, `audio`, `math` are module paths within those reserved spaces,
- `main.pbs` and `mod.barrel` form the interface module contents.

## 5. Logical Mapping

The compiler must treat the physical layout as a logical stdlib environment.

Required mapping:

- `stdlib/<N>/sdk/gfx` -> `@sdk:gfx`
- `stdlib/<N>/sdk/composer` -> `@sdk:composer`
- `stdlib/<N>/sdk/asset` -> `@sdk:asset`
- `stdlib/<N>/sdk/audio` -> `@sdk:audio`
- `stdlib/<N>/core/math` -> `@core:math`
- `stdlib/<N>/core/math/vector` -> `@core:math/vector`

Rules:

- physical storage is an implementation detail,
- logical module identity is authoritative,
- callers of the resolver should work with logical addresses such as `@sdk:gfx` and `@sdk:composer`, not resource paths.

## 6. Module File Convention

For the Studio implementation, each stdlib module should follow the same structural convention as ordinary PBS modules:

- one or more `.pbs` files,
- exactly one `mod.barrel`.

Recommended minimum convention:

- `main.pbs`
- `mod.barrel`

Rules:

- `main.pbs` is a convention, not a language-level requirement,
- the module remains an ordinary PBS module from the parser's perspective,
- it is interpreted under interface-module semantics because it lives in a reserved stdlib project space.

## 7. Required Compiler Abstractions

The compiler should not reach directly into `resources` paths throughout the frontend.

At minimum, the PBS frontend should define abstractions equivalent to:

### 7.1 `StdlibEnvironment`

Responsibility:

- represent the selected stdlib line for one compilation,
- expose reserved project spaces,
- provide access to interface modules by logical module address.

Minimum operations:

- select stdlib major line,
- answer whether a reserved project space exists,
- open a module by logical address.

### 7.2 `StdlibModuleResolver`

Responsibility:

- resolve logical imports in reserved project spaces,
- map `@sdk:*` and `@core:*` imports to concrete interface module sources,
- reject unknown stdlib modules deterministically.

Minimum operations:

- `resolve(@sdk:gfx)`
- `resolve(@sdk:composer)`
- `resolve(@core:math/vector)`

### 7.3 `StdlibModuleSource`

Responsibility:

- represent the source files of one stdlib module,
- provide access to the module's `.pbs` files and `mod.barrel`,
- hide whether content came from disk, `resources`, or another source.

Minimum contents:

- module address
- list of `.pbs` source texts or streams
- `mod.barrel` source text or stream

### 7.4 `InterfaceModuleLoader`

Responsibility:

- parse a stdlib module source using the normal PBS parser,
- validate it in interface-module mode,
- return compiler-facing symbols and metadata.

Minimum outputs:

- exported symbols
- declared types
- host owners
- host method signatures
- reserved attribute metadata such as `[Host(...)]`

## 8. Loading Algorithm

The recommended Studio compiler flow is:

1. read the root `prometeu.json`,
2. parse and normalize `stdlib`,
3. construct `StdlibEnvironment` for that stdlib major,
4. create a `StdlibModuleResolver`,
5. when an import targets a reserved project space, resolve it through the stdlib resolver,
6. obtain a `StdlibModuleSource`,
7. parse the module with the standard PBS parser,
8. validate it under interface-module semantic rules,
9. cache the resulting interface module graph for the duration of the compilation.

Rules:

- reserved stdlib modules must not be handled through ordinary dependency resolution,
- ordinary dependency modules must not be handled through the stdlib resolver,
- a failed stdlib import is a deterministic compile-time error.

## 9. Attributes and Interface Metadata

Stdlib interface modules may contain reserved compile-time attributes such as:

```pbs
declare host Gfx {
  [Host(module = "gfx", name = "draw_pixel", version = 1)]
  fn draw_pixel(x: int, y: int, c: color);
}
```

or:

```pbs
declare host LowAssets {
  [Host(module = "asset", name = "load", version = 1)]
  [Capability(name = "asset")]
  [AssetLowering(param = 0)]
  fn load(addressable: Addressable, slot: int) -> (status: int, loading_handle: int);
}
```

or:

```pbs
declare host LowComposer {
  [Host(module = "composer", name = "emit_sprite", version = 1)]
  [Capability(name = "gfx")]
  fn emit_sprite(
    glyph_id: int,
    palette_id: int,
    x: int,
    y: int,
    layer: int,
    bank_id: int,
    flip_x: bool,
    flip_y: bool,
    priority: int
  ) -> int;
}
```

Rules:

- the parser reads the attribute as part of the interface module source,
- the interface-module loader validates that the attribute is legal in that position,
- the compiler stores the extracted metadata in its interface graph,
- the raw attribute surface is not treated as a runtime object,
- later lowering stages may consume the extracted metadata to produce PBX host-binding declarations.
- stdlib line `1` MUST expose the sprite-composition interface module at `@sdk:composer`,
- that module MUST declare `LowComposer` and public service `Composer`,
- that module MUST use runtime module `composer` and capability `gfx`,
- that module MUST expose `bind_scene(scene_bank_id: int) -> int`,
- that module MUST expose `unbind_scene() -> int`,
- that module MUST expose `emit_sprite(glyph_id: int, palette_id: int, x: int, y: int, layer: int, bank_id: int, flip_x: bool, flip_y: bool, priority: int) -> int`,
- stdlib line `1` MUST NOT expose `Gfx.set_sprite`,
- stdlib line `1` MUST expose the low-level asset interface module at `@sdk:asset`,
- that module MUST declare `LowAssets`,
- that module MUST use runtime module `asset` and capability `asset`,
- that module MUST use the runtime-aligned signatures and reserved lowering metadata:
  - `load(addressable: Addressable, slot: int) -> (status: int, loading_handle: int)` together with `[AssetLowering(param = 0)]`
  - `status(loading_handle: int) -> int`
  - `commit(loading_handle: int) -> int`
  - `cancel(loading_handle: int) -> int`

## 10. Resources as an Implementation Strategy

For the Studio PBS frontend, packaging stdlib interface modules in frontend `resources` is a valid implementation strategy.

Rules:

- `resources` packaging is implementation-level, not language-level,
- the compiler should still access stdlib modules through `StdlibEnvironment` and related abstractions,
- code outside the stdlib loader should not depend on resource path layout directly.

Rationale:

- `resources` gives a simple bootstrap path,
- stdlib evolves as real source artifacts,
- the frontend avoids hardcoded built-ins,
- the implementation remains replaceable later.

## 11. Caching and Reuse

The compiler may cache stdlib interface modules within one compilation or across compilations.

Rules:

- caching must not change observable semantics,
- cache keys should include at least the stdlib major line and logical module address,
- cached modules must preserve the same parsed declarations and attribute metadata as uncached loads.

## 12. Current Decision Summary

The current Studio direction is:

1. the stdlib environment is loaded as real PBS interface modules,
2. the initial implementation may live under frontend `resources`,
3. the logical model remains `stdlib line -> reserved project space -> module path`,
4. the compiler should use explicit abstractions such as `StdlibEnvironment` and `StdlibModuleResolver`,
5. stdlib interface modules are parsed with the normal PBS parser and validated in interface-module mode,
6. reserved attributes such as `[Host(...)]` are extracted as compile-time metadata for later lowering.
