prometeu-studio/docs/specs/compiler-languages/pbs/5. Manifest, Stdlib, and SDK Resolution Specification.md

15 KiB

PBS Manifest, Module, Stdlib, and SDK Resolution Specification

Status: Draft v2 (Normative)
Applies to: prometeu.json, project and module terminology, workspace dependency resolution, stdlib selection, reserved stdlib projects, interface-module loading, and compile-time SDK metadata

1. Purpose

This document defines the normative compile-time model for:

  • project manifests,
  • project and module identity,
  • import resolution,
  • stdlib selection,
  • reserved stdlib project spaces,
  • stdlib interface modules,
  • and the compile-time lifecycle of SDK host-binding metadata.

This document is the authority for how the compiler discovers and loads:

  • ordinary project modules,
  • reserved stdlib modules such as @sdk:gfx,
  • compile-time reserved metadata attached to those reserved modules,
  • and interface-only service facades that wrap host surfaces for source ergonomics.

This document does not define runtime load behavior. PBX host-binding emission and loader-side syscall resolution are defined by the Host ABI Binding and Loader Resolution Specification.

2. Scope

This document defines:

  • the role of language in prometeu.json,
  • the role of stdlib in prometeu.json,
  • the distinction between projects, modules, and imports,
  • the distinction between ordinary project dependencies and the stdlib environment,
  • root-project ownership of the effective stdlib line of a build,
  • reserved project spaces such as @sdk:* and @core:*,
  • the source model for stdlib interface modules,
  • the compile-time role of reserved attributes such as [Host(...)].

This document does not define:

  • PBX binary layout,
  • loader-side syscall resolution,
  • cartridge capability policy,
  • package registry protocol details,
  • runtime reflection over attributes.

3. Core Terms

3.1 Project

A project is the unit described by prometeu.json.

Rules:

  • A project has a name, version, language, stdlib, and dependencies.
  • A project is the unit resolved by the workspace dependency graph.
  • A project is the unit selected by a dependency declaration.
  • A project is the unit published and versioned by ordinary dependency resolution.
  • A project contains one or more modules.

3.2 Module

A module is the unit of source import inside a project.

Rules:

  • Every .pbs source file belongs to exactly one module.
  • Every module belongs to exactly one project.
  • Imports select modules, not whole projects.
  • A module is addressed by a project name plus a module path.

3.3 Canonical module address

The canonical PBS module address format is:

@project:path/to/module

Rules:

  • project identifies the owning project space.
  • path/to/module identifies the module path inside that project.
  • Module path segments are directory-style segments separated by /.
  • The syntax is Java-like in organization and JavaScript-like in import surface.

Examples:

  • @game:player/state
  • @physics:collision/shapes
  • @sdk:gfx
  • @core:math/vector

3.4 Reserved project spaces

The following project spaces are reserved:

  • @sdk:*
  • @core:*

Rules:

  • Reserved project spaces belong to the selected stdlib environment.
  • Ordinary user-authored projects MUST NOT publish modules into reserved project spaces.
  • Ordinary dependency resolution MUST NOT satisfy @sdk:* or @core:* imports from user projects.
  • Reserved project spaces are resolved only from the selected stdlib environment.

4. prometeu.json

4.1 Required fields

The manifest format relevant to this document is:

{
  "name": "main",
  "version": "1.0.0",
  "language": "pbs",
  "stdlib": "1",
  "dependencies": [
    { "name": "dep1", "version": "1.0.0" }
  ]
}

Rules:

  • name identifies the project.
  • version identifies the project version.
  • language identifies the frontend language.
  • stdlib identifies the selected stdlib major line.
  • dependencies declare ordinary project dependencies only.

4.2 language

Rules:

  • language selects the compiler frontend.
  • All projects in one resolved workspace MUST use the same language.
  • Unknown language values are compile-time errors.

4.3 stdlib

Rules:

  • stdlib is required in every manifest.
  • stdlib uses major-only version syntax in v1.
  • The manifest surface for stdlib is a string containing a positive decimal integer.
  • Examples of valid values: "1", "2".
  • Examples of invalid values: "0", "01", "1.0", "v1", "".
  • Implementations SHOULD normalize stdlib internally to an integer major version.

Diagnostics:

  • Missing stdlib is a manifest error.
  • Invalid major-only format is a manifest error.

5. Ordinary Dependencies vs Stdlib Environment

5.1 Ordinary dependencies

Rules:

  • dependencies model ordinary project relationships only.
  • A dependency may be local or registry-based according to the compiler's dependency resolver.
  • Dependencies contribute source projects, modules, and project-graph edges.
  • dependencies do not declare stdlib projects.

5.2 Stdlib environment

Rules:

  • The stdlib environment is not declared through dependencies.
  • The stdlib environment is selected through stdlib.
  • @sdk:* and @core:* imports resolve against the stdlib environment selected for the build.
  • The presence of stdlib modules does not imply automatic visibility in source.
  • User code MUST still import stdlib modules explicitly through ordinary import syntax.

Example:

import { Gfx, color } from @sdk:gfx;

let c: color = color.red;
Gfx.draw_pixel(1, 1, c);

Rules:

  • Gfx is not implicitly in scope.
  • Gfx becomes visible only through import.
  • The compiler accepts that import because the selected stdlib environment exposes @sdk:gfx.

6. Effective Stdlib of the Build

The root project owns the effective stdlib line of the build.

Rules:

  • The resolved workspace has exactly one effective stdlib major version.
  • The effective stdlib major version is taken from the root project manifest.
  • All projects in the workspace compile under that same effective stdlib line.
  • Dependency projects do not activate separate stdlib environments for themselves.

This means:

  • stdlib on a dependency is a compatibility declaration,
  • not an instruction to switch the compiler into another stdlib mode for that dependency.

7. Stdlib Compatibility Across Dependency Projects

Let:

  • R be the root project's stdlib major,
  • D be a dependency project's stdlib major.

Rules:

  • If D > R, dependency resolution MUST fail with a deterministic compile-time error.
  • If D <= R, dependency resolution MAY proceed.
  • D <= R does not guarantee semantic compatibility of all APIs used by the dependency; it only means the dependency is not asking for a newer stdlib line than the root selected.

Rationale:

  • the build target is chosen by the root project,
  • dependency projects may target the same or an older stdlib line,
  • dependency projects must not force the build to silently adopt a newer stdlib than the root requested.

Example:

  • root stdlib = "1", dependency stdlib = "2": error.
  • root stdlib = "2", dependency stdlib = "1": allowed.
  • root stdlib = "1", dependency stdlib = "1": allowed.

8. Import Resolution

8.1 Resolution sources

The compiler resolves imports against exactly two sources:

  1. the selected stdlib environment,
  2. the resolved ordinary project dependency graph.

Rules:

  • @sdk:* and @core:* are resolved only against the stdlib environment,
  • all other @project:* imports are resolved only against the ordinary dependency graph,
  • there is no fallback from reserved stdlib resolution to ordinary dependencies,
  • there is no fallback from ordinary dependency resolution to reserved stdlib spaces.

8.2 Resolution algorithm

For an import:

import { X } from @project:path/to/module;

the compiler MUST:

  1. parse the project space and module path,
  2. determine whether the project space is reserved,
  3. if reserved, resolve the module from the selected stdlib environment,
  4. otherwise, resolve the module from the root project or its dependency graph,
  5. load the target module,
  6. resolve the requested exported names from that module.

Failure at any step is a deterministic compile-time error.

9. Stdlib Interface Modules

9.1 Interface-module model

The selected stdlib environment MUST provide its modules as PBS-like interface modules.

Rules:

  • Stdlib modules are .pbs modules loaded by the compiler.
  • Stdlib interface modules use the same parser surface as ordinary PBS modules.
  • Stdlib interface modules are interpreted in interface-module mode.
  • Interface-module mode is non-executable and compile-time only.
  • Interface modules participate in import resolution and type checking.
  • Interface modules do not emit executable bytecode by themselves.

9.2 Allowed role

At minimum, an interface module may provide:

  • exported names,
  • types,
  • enums,
  • host owners,
  • method signatures,
  • compile-time metadata such as canonical host-binding attributes.

This list fixes the currently required declarative role of interface modules, but does not by itself freeze the final complete declaration set allowed in interface-module mode.

An interface module is not runtime code.

9.3 Interface-module restrictions

At minimum, an interface module MUST remain declarative.

Rules:

  • Interface modules MUST NOT contain top-level executable statements.
  • Interface modules MUST NOT require runtime initialization.
  • Interface modules MUST NOT introduce executable method bodies that would emit bytecode.
  • declare host is permitted only in reserved stdlib/toolchain interface modules.
  • Reserved attributes such as [Host(...)] are permitted only where another specification explicitly allows them.

9.4 Example interface module

Illustrative stdlib interface module:

declare enum color(red, green, blue);

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

Rules:

  • This module is valid only in a reserved stdlib/interface-module context.
  • It contributes compile-time symbols and metadata.
  • It does not produce executable bytecode by itself.

10. Compiler Loading of the Stdlib Environment

The compiler loads the stdlib environment from the stdlib line selected by the root project.

Required model:

  1. Read the root prometeu.json.
  2. Determine the effective stdlib major line.
  3. Mount or select the matching stdlib environment.
  4. Expose its reserved project spaces such as @sdk:* and @core:*.
  5. Load interface modules from that environment on demand during import resolution.
  6. Parse those modules with the ordinary PBS parser.
  7. Validate them under interface-module semantic rules.
  8. Populate the compiler's symbol graph from their exported declarations and attributes.

Rules:

  • The compiler MUST behave as if it were loading real modules, not hardcoded symbol tables.
  • The physical storage format of the stdlib environment is an implementation detail.
  • The compiler MAY load the stdlib environment from disk, embedded resources, a virtual filesystem, or another implementation-defined source with equivalent behavior.
  • For the Studio PBS frontend, embedding stdlib interface modules under frontend resources is a valid implementation strategy.

11. Reserved Attributes and Metadata Lifecycle

11.1 General rule

Attributes are compile-time metadata, not runtime objects.

Rules:

  • Attributes are parsed as part of the source module.
  • Attributes participate in declaration validation and compiler metadata extraction.
  • Attributes are not exported as ordinary values, types, or runtime-reflectable objects.
  • Attributes do not automatically survive into bytecode, PBX, or runtime metadata.

11.2 Host attribute

The canonical reserved host-binding attribute is:

[Host(module = "gfx", name = "draw_pixel", version = 1)]

Rules:

  • Host is valid only on a host method signature declared directly inside a reserved stdlib/interface-module declare host body.
  • Host provides the canonical host primitive identity used by compiler lowering.
  • module and name are string literals.
  • version is a positive integer literal.
  • The attribute surface itself is compile-time only.

11.3 Lowering effect

Although the attribute syntax itself is compile-time only, its semantic effect may be lowered.

Rules:

  • The compiler consumes Host metadata while resolving host-backed SDK members.
  • The compiler uses that metadata to emit runtime-facing host-binding declarations as defined by the Host ABI Binding specification.
  • The compiler does not export the raw [Host(...)] syntax into runtime as a source-level attribute object.

In other words:

  • the attribute is compile-time metadata,
  • the lowered host-binding declaration is runtime-facing artifact metadata,
  • they are not the same thing.

12. Relationship to declare host

Rules:

  • declare host remains reserved to SDK/toolchain-controlled modules.
  • Ordinary user-authored project modules do not declare canonical host bindings directly.
  • User code consumes SDK exports through normal imports.
  • SDK-facing surfaces such as Gfx.draw_pixel(...) are resolved by the compiler against the selected stdlib environment.
  • Canonical host identity comes from reserved host-binding metadata such as [Host(...)], not from the source spelling of the imported owner.

13. Project Publication and Distribution

Rules:

  • Ordinary publication and dependency resolution operate at project granularity.
  • A published project version contains one or more modules.
  • Imports consume modules from a resolved project.
  • The stdlib environment is distributed separately from ordinary project dependencies.
  • The stdlib environment is selected by stdlib, not by dependencies.

14. Non-Goals

  • Making stdlib modules implicitly visible without import.
  • Treating the stdlib as an ordinary dependency in the workspace graph.
  • Allowing each dependency project to activate its own stdlib line.
  • Hardcoding stdlib symbols directly into the compiler without a module model.
  • Runtime reflection over source-level attributes.

15. Open Items Deferred

The following remain intentionally deferred:

  1. Exact on-disk distribution format of stdlib environment packs.
  2. Registry/publication protocol details for ordinary projects.
  3. Final diagnostics catalog for all import-resolution failures.
  4. Full list of declarations allowed inside interface modules beyond the already-fixed reserved host surfaces.

16. Current Decision Summary

The current PBS design direction is:

  1. prometeu.json declares language and stdlib separately.
  2. A project is the unit described by prometeu.json and selected by dependencies.
  3. A module is the unit selected by import.
  4. Canonical module addresses use @project:path/to/module.
  5. @sdk:* and @core:* are reserved stdlib project spaces.
  6. The root project selects the effective stdlib line for the whole build.
  7. Dependency projects with a higher stdlib requirement than the root are rejected.
  8. Stdlib modules are loaded as PBS-like interface modules, not as ordinary dependencies.
  9. Interface modules are compile-time-only in packaging terms: they may carry declarative service facades with method bodies for source-level API ergonomics, but they still do not emit executable bytecode as standalone modules.
  10. declare host remains reserved to stdlib/toolchain interface modules.
  11. Reserved attributes such as [Host(...)] are compile-time metadata, not runtime objects.
  12. The compiler consumes Host metadata to produce runtime-facing host-binding artifacts defined elsewhere.