prometeu-studio/docs/specs/pbs/7. Cartridge Manifest and Runtime Capabilities Specification.md
2026-03-24 13:42:17 +00:00

247 lines
6.7 KiB
Markdown

# Cartridge Manifest and Runtime Capabilities Specification
Status: Draft v1 (Temporary)
Applies to: `manifest.json` in Prometeu cartridges, runtime capability declaration, and loader capability input
## 1. Purpose
This document defines the current cartridge manifest contract relevant to runtime loading.
Its purpose is to stabilize:
- the JSON surface consumed by the cartridge loader,
- the declaration of cartridge-requested runtime capabilities,
- the boundary between cartridge packaging and loader authority,
- the conversion from manifest-facing capability names to runtime capability flags.
This document is intentionally temporary and limited.
It does not define cartridge publishing, signing, or store policy.
## 2. Scope
This document defines:
- the role of `manifest.json` in cartridge loading,
- the current required manifest fields,
- the new `capabilities` field,
- the nominal capability enumeration used in JSON,
- the mapping from nominal capabilities to runtime `CapFlags`,
- the role of the loader when combining manifest capabilities with PBX `SYSC`.
This document does not define:
- the full package format beyond the current directory cartridge contract,
- policy UI or permission prompts,
- cartridge signing or trust chains,
- final platform grant policy when the host wants to reduce requested capabilities.
## 3. Current Cartridge Manifest Role
The cartridge manifest is an external load-time descriptor for a cartridge.
It is not compiled from PBS source directly.
It is produced by cartridge packaging tooling and consumed by the runtime loader.
The manifest currently carries:
- cartridge identity and metadata,
- app entry information,
- asset metadata,
- preload metadata.
This document adds runtime capability declaration to that same manifest.
## 4. Manifest Shape
The current manifest shape relevant to this document is:
```json
{
"magic": "PMTU",
"cartridge_version": 1,
"app_id": 1001,
"title": "Example",
"app_version": "1.0.0",
"app_mode": "game",
"entrypoint": "main",
"capabilities": ["gfx", "input"],
"asset_table": [],
"preload": []
}
```
Rules:
- `magic` identifies a Prometeu cartridge manifest,
- `cartridge_version` identifies the cartridge manifest format line,
- `entrypoint` identifies the runtime entrypoint,
- `capabilities` declares the cartridge's requested runtime capabilities,
- `asset_table` and `preload` remain separate concerns.
## 5. `capabilities`
### 5.1 General rules
`capabilities` is a manifest-facing nominal list.
Rules:
- `capabilities` is optional,
- when omitted, it behaves as an empty list,
- capability names are canonical lowercase identifiers,
- duplicate entries are invalid,
- unknown capability names are manifest errors.
### 5.2 Nominal capability set
The current nominal capability set is:
- `system`
- `gfx`
- `input`
- `audio`
- `fs`
- `log`
- `asset`
- `bank`
These names are the normative manifest-facing representation.
## 6. Relationship to Runtime `CapFlags`
The runtime may continue to represent capabilities internally as a bitflag set.
That internal representation is an implementation detail.
The normative external model is:
- a nominal capability enum in the manifest,
- deterministic conversion by the loader into runtime flags.
Canonical mapping:
- `system` -> `SYSTEM`
- `gfx` -> `GFX`
- `input` -> `INPUT`
- `audio` -> `AUDIO`
- `fs` -> `FS`
- `log` -> `LOG`
- `asset` -> `ASSET`
- `bank` -> `BANK`
This means the recommended runtime design is:
1. deserialize `capabilities` into a nominal enum or equivalent validated representation,
2. convert that validated set into internal `CapFlags`,
3. use those flags during host-binding resolution.
## 7. Loader Semantics
The loader consumes both:
- the cartridge manifest,
- and the PBX `SYSC` table.
Required behavior:
1. parse `manifest.json`,
2. parse `capabilities`,
3. convert the nominal capability list to internal capability flags,
4. parse `program.pbx`,
5. resolve each `SYSC` entry against the host registry,
6. obtain required capabilities from resolved syscall metadata,
7. fail if required capabilities are not granted by the manifest/policy environment.
The manifest alone does not make a program valid.
The manifest must be consistent with the actual syscalls required by the PBX.
## 8. Requested vs Granted Authority
The manifest declares requested cartridge capabilities.
The loader/runtime environment is the authority that decides what is granted.
Current direction:
- in the initial runtime model, the manifest may act as the immediate source of granted capabilities,
- a future platform policy layer may reduce or deny requested capabilities before final load.
Normative rule:
- the compiler does not grant capabilities,
- the PBX does not grant capabilities,
- cartridge/runtime loading is the authority boundary.
## 9. Relationship to Compiler and Packer
Responsibilities are split as follows:
Compiler:
- compiles source to PBX,
- emits `SYSC`,
- emits `HOSTCALL <sysc_index>`,
- does not grant authority.
Packer:
- produces the cartridge manifest,
- declares requested runtime capabilities,
- packages `manifest.json`, `program.pbx`, and assets.
Loader:
- reads the manifest,
- derives granted capability flags,
- validates those capabilities against PBX host requirements.
## 10. Validation Rules
The cartridge manifest must fail validation if:
1. `capabilities` contains an unknown name,
2. `capabilities` contains duplicates,
3. `capabilities` is not an array of strings or nominal enum values under the chosen serialization form.
Cartridge load must fail if:
1. the manifest omits a capability required by a resolved `SYSC` entry,
2. a future platform policy denies a capability required by a resolved `SYSC` entry.
## 11. Serialization Guidance
The recommended manifest-facing model is a nominal enum list, not numeric masks.
Recommended JSON:
```json
{
"capabilities": ["gfx", "input", "audio"]
}
```
Rejected as normative surface:
- raw integer bitmasks,
- hex masks,
- unnamed positional arrays.
Rationale:
- nominal capability names are readable,
- manifest diffs remain understandable,
- packer and tooling validation is straightforward,
- runtime may still use bitflags internally after conversion.
## 12. Current Decision Summary
The current temporary contract is:
1. `manifest.json` is the cartridge-facing load descriptor.
2. `capabilities` is declared in `manifest.json`, not in `prometeu.json`.
3. `capabilities` uses nominal canonical names such as `gfx` and `audio`.
4. The runtime may keep using internal `CapFlags`.
5. The loader converts nominal manifest capabilities into internal flags.
6. PBX `SYSC` declares required host bindings, not authority.
7. Loader validation fails if PBX host requirements exceed granted cartridge capabilities.