implements PLN-0046 profile separation spec

This commit is contained in:
bQUARKz 2026-05-14 13:24:09 +01:00
parent e3ac3dfd06
commit da908ffcb4
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
5 changed files with 61 additions and 4 deletions

View File

@ -29,4 +29,4 @@
{"type":"discussion","id":"DSC-0018","status":"done","ticket":"asset-load-asset-id-int-contract","title":"Asset Load Asset ID Int Contract","created_at":"2026-03-27","updated_at":"2026-03-27","tags":["asset","runtime","abi"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0019","file":"discussion/lessons/DSC-0018-asset-load-asset-id-int-contract/LSN-0019-asset-load-id-abi-convergence.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"}]} {"type":"discussion","id":"DSC-0018","status":"done","ticket":"asset-load-asset-id-int-contract","title":"Asset Load Asset ID Int Contract","created_at":"2026-03-27","updated_at":"2026-03-27","tags":["asset","runtime","abi"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0019","file":"discussion/lessons/DSC-0018-asset-load-asset-id-int-contract/LSN-0019-asset-load-id-abi-convergence.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"}]}
{"type":"discussion","id":"DSC-0019","status":"done","ticket":"jenkinsfile-correction","title":"Jenkinsfile Correction and Relocation","created_at":"2026-04-07","updated_at":"2026-04-07","tags":["ci","jenkins"],"agendas":[{"id":"AGD-0017","file":"AGD-0017-jenkinsfile-correction.md","status":"done","created_at":"2026-04-07","updated_at":"2026-04-07"}],"decisions":[{"id":"DEC-0002","file":"DEC-0002-jenkinsfile-strategy.md","status":"accepted","created_at":"2026-04-07","updated_at":"2026-04-07"}],"plans":[{"id":"PLN-0002","file":"PLN-0002-jenkinsfile-execution.md","status":"done","created_at":"2026-04-07","updated_at":"2026-04-07"}],"lessons":[{"id":"LSN-0020","file":"discussion/lessons/DSC-0019-jenkins-ci-standardization/LSN-0020-jenkins-standard-relocation.md","status":"done","created_at":"2026-04-07","updated_at":"2026-04-07"}]} {"type":"discussion","id":"DSC-0019","status":"done","ticket":"jenkinsfile-correction","title":"Jenkinsfile Correction and Relocation","created_at":"2026-04-07","updated_at":"2026-04-07","tags":["ci","jenkins"],"agendas":[{"id":"AGD-0017","file":"AGD-0017-jenkinsfile-correction.md","status":"done","created_at":"2026-04-07","updated_at":"2026-04-07"}],"decisions":[{"id":"DEC-0002","file":"DEC-0002-jenkinsfile-strategy.md","status":"accepted","created_at":"2026-04-07","updated_at":"2026-04-07"}],"plans":[{"id":"PLN-0002","file":"PLN-0002-jenkinsfile-execution.md","status":"done","created_at":"2026-04-07","updated_at":"2026-04-07"}],"lessons":[{"id":"LSN-0020","file":"discussion/lessons/DSC-0019-jenkins-ci-standardization/LSN-0020-jenkins-standard-relocation.md","status":"done","created_at":"2026-04-07","updated_at":"2026-04-07"}]}
{"type":"discussion","id":"DSC-0030","status":"done","ticket":"internal-viewport-270p","title":"Agenda - Internal Viewport 270p (480x270)","created_at":"2026-04-27","updated_at":"2026-04-28","tags":["gfx","runtime","viewport","resolution","frame-composer","host"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0039","file":"discussion/lessons/DSC-0030-internal-viewport-270p/LSN-0039-resolution-baseline-changes-are-runtime-wide-contracts.md","status":"done","created_at":"2026-04-28","updated_at":"2026-04-28"}]} {"type":"discussion","id":"DSC-0030","status":"done","ticket":"internal-viewport-270p","title":"Agenda - Internal Viewport 270p (480x270)","created_at":"2026-04-27","updated_at":"2026-04-28","tags":["gfx","runtime","viewport","resolution","frame-composer","host"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0039","file":"discussion/lessons/DSC-0030-internal-viewport-270p/LSN-0039-resolution-baseline-changes-are-runtime-wide-contracts.md","status":"done","created_at":"2026-04-28","updated_at":"2026-04-28"}]}
{"type":"discussion","id":"DSC-0031","status":"in_progress","ticket":"runtime-mode-separation-game-system","title":"Agenda - Runtime Mode Separation: Game and System","created_at":"2026-05-11","updated_at":"2026-05-14","tags":["runtime","firmware","hub","system-apps","game-mode","scheduler"],"agendas":[{"id":"AGD-0031","file":"AGD-0031-runtime-mode-separation-game-system.md","status":"accepted","created_at":"2026-05-11","updated_at":"2026-05-14"}],"decisions":[{"id":"DEC-0023","file":"DEC-0023-system-pipeline-separation.md","status":"accepted","created_at":"2026-05-14","updated_at":"2026-05-14"}],"plans":[{"id":"PLN-0046","file":"PLN-0046-profile-separation-specification.md","status":"open","created_at":"2026-05-14","updated_at":"2026-05-14","ref_decisions":["DEC-0023"]},{"id":"PLN-0047","file":"PLN-0047-firmware-runtime-profile-dispatch.md","status":"open","created_at":"2026-05-14","updated_at":"2026-05-14","ref_decisions":["DEC-0023"]},{"id":"PLN-0048","file":"PLN-0048-minimal-system-hub-pipeline.md","status":"open","created_at":"2026-05-14","updated_at":"2026-05-14","ref_decisions":["DEC-0023"]},{"id":"PLN-0049","file":"PLN-0049-system-profile-abi-gates.md","status":"open","created_at":"2026-05-14","updated_at":"2026-05-14","ref_decisions":["DEC-0023"]},{"id":"PLN-0050","file":"PLN-0050-system-pipeline-evidence-and-learning.md","status":"open","created_at":"2026-05-14","updated_at":"2026-05-14","ref_decisions":["DEC-0023"]}],"lessons":[]} {"type":"discussion","id":"DSC-0031","status":"in_progress","ticket":"runtime-mode-separation-game-system","title":"Agenda - Runtime Mode Separation: Game and System","created_at":"2026-05-11","updated_at":"2026-05-14","tags":["runtime","firmware","hub","system-apps","game-mode","scheduler"],"agendas":[{"id":"AGD-0031","file":"AGD-0031-runtime-mode-separation-game-system.md","status":"accepted","created_at":"2026-05-11","updated_at":"2026-05-14"}],"decisions":[{"id":"DEC-0023","file":"DEC-0023-system-pipeline-separation.md","status":"accepted","created_at":"2026-05-14","updated_at":"2026-05-14"}],"plans":[{"id":"PLN-0046","file":"PLN-0046-profile-separation-specification.md","status":"done","created_at":"2026-05-14","updated_at":"2026-05-14","ref_decisions":["DEC-0023"]},{"id":"PLN-0047","file":"PLN-0047-firmware-runtime-profile-dispatch.md","status":"open","created_at":"2026-05-14","updated_at":"2026-05-14","ref_decisions":["DEC-0023"]},{"id":"PLN-0048","file":"PLN-0048-minimal-system-hub-pipeline.md","status":"open","created_at":"2026-05-14","updated_at":"2026-05-14","ref_decisions":["DEC-0023"]},{"id":"PLN-0049","file":"PLN-0049-system-profile-abi-gates.md","status":"open","created_at":"2026-05-14","updated_at":"2026-05-14","ref_decisions":["DEC-0023"]},{"id":"PLN-0050","file":"PLN-0050-system-pipeline-evidence-and-learning.md","status":"open","created_at":"2026-05-14","updated_at":"2026-05-14","ref_decisions":["DEC-0023"]}],"lessons":[]}

View File

@ -2,7 +2,7 @@
id: PLN-0046 id: PLN-0046
ticket: runtime-mode-separation-game-system ticket: runtime-mode-separation-game-system
title: Profile Separation Specification title: Profile Separation Specification
status: open status: done
created: 2026-05-14 created: 2026-05-14
completed: completed:
ref_decisions: [DEC-0023] ref_decisions: [DEC-0023]

View File

@ -75,6 +75,9 @@ If validation fails, cartridge loading is rejected before execution.
- `Game` - `Game`
- `System` - `System`
`app_mode` is the runtime profile discriminator. No separate manifest `target`
field participates in profile selection.
Cartridge boot is protocol-driven, not manifest-driven. Cartridge boot is protocol-driven, not manifest-driven.
The executable entrypoint of a valid cartridge is always `func_id = 0`. The executable entrypoint of a valid cartridge is always `func_id = 0`.
@ -85,6 +88,37 @@ This means:
- firmware/runtime loads the cartridge and starts execution from `func_id = 0`; - firmware/runtime loads the cartridge and starts execution from `func_id = 0`;
- nominal exports may exist for linking or introspection, but they do not hold boot authority. - nominal exports may exist for linking or introspection, but they do not hold boot authority.
## 5.1 Runtime Profiles
`Game` and `System` are distinct runtime profiles.
`Game` cartridges use the game pipeline. The game profile owns the public game
surfaces for frame composition, GFX, game input, banks, sprites, and
memory-card-style persistence.
`System` cartridges use a Runtime/Hub pipeline dedicated to system UI and app
hosting. The system profile must not inherit the game stdlib or game ABI as its
public authoring surface. In particular, `System` must not expose
`FrameComposer`, `Gfx`, game `Input`, banks, sprites, or game memory cards as
public profile APIs.
Future `System` APIs may be transported through syscalls, but syscall transport
does not define the conceptual ABI boundary. The author-facing contract for
system apps is a dedicated `System` profile ABI and stdlib/framework.
The following contracts are intentionally deferred from this cartridge chapter:
- complete WindowManager design;
- component tree and lifecycle semantics;
- rich invalidation and transitions;
- public PBS `System` ABI;
- multitasking and scheduler semantics;
- detailed `System` filesystem semantics.
The positive filesystem contract for `System` remains owned by the dedicated
filesystem discussion/spec work. The only profile rule fixed here is negative:
`System` does not use game memory cards as its public storage model.
## 6 Assets and Preload ## 6 Assets and Preload
`assets.pa` is the runtime-facing asset artifact consumed by the current runtime. `assets.pa` is the runtime-facing asset artifact consumed by the current runtime.

View File

@ -40,11 +40,18 @@ When the boot target is `Cartridge`:
For a cartridge boot target: For a cartridge boot target:
- `Game` cartridges transition into game-running flow; - `Game` cartridges transition into the game-running pipeline;
- `System` cartridges are initialized and integrated into the Hub/window path. - `System` cartridges transition into a Runtime/Hub pipeline dedicated to
system UI and app hosting.
This preserves the distinction between machine firmware state and app execution mode. This preserves the distinction between machine firmware state and app execution mode.
The `System` route must not be treated as the game pipeline running inside a
window. It is a separate runtime profile path oriented around Hub ownership and
WindowManager integration. The initial implementation may be minimal, but the
routing boundary is normative: `System` does not enter `GameRunning` as its
profile pipeline.
## 4 Host CLI Relationship ## 4 Host CLI Relationship
Typical host-facing boot intents are: Typical host-facing boot intents are:
@ -67,6 +74,10 @@ Boot target selection feeds into firmware states such as:
- `GameRunning` - `GameRunning`
- `AppCrashes` - `AppCrashes`
Additional firmware states may represent dedicated `System` profile execution.
Such states are part of the Runtime/Hub route and do not change the `Game`
pipeline contract.
Boot target is not itself a firmware state. It is an input to the firmware state machine. Boot target is not itself a firmware state. It is an input to the firmware state machine.
## 6 Debug Boot ## 6 Debug Boot

View File

@ -52,6 +52,12 @@ This identity is:
Input queries are VM-owned intrinsic calls in v1 and are outside the syscall identity space. Input queries are VM-owned intrinsic calls in v1 and are outside the syscall identity space.
Syscall identity is transport, not the conceptual boundary for runtime
profiles. `Game` and `System` may both use syscall transport internally or at
their ABI edge, but that does not make their public authoring surfaces the same
ABI. `System` APIs, when exposed to PBS or other guest languages, belong to a
dedicated `System` profile ABI and stdlib/framework.
## 3 Syscall Resolution ## 3 Syscall Resolution
The host maintains a registry: The host maintains a registry:
@ -173,6 +179,9 @@ Return shape must also follow the transversal status-first policy in [`16a-sysca
The game memcard profile uses module `mem` with status-first return shapes. The game memcard profile uses module `mem` with status-first return shapes.
`mem` is a domain layer backed by runtime `fs` (it is not a separate storage backend). `mem` is a domain layer backed by runtime `fs` (it is not a separate storage backend).
The `mem` module is a game profile surface. It is not the public storage model
for `System` profile apps.
Canonical operations in v1 are: Canonical operations in v1 are:
- `mem.slot_count() -> (status, count)` - `mem.slot_count() -> (status, count)`
@ -215,6 +224,9 @@ For `asset.load`:
The canonical frame-orchestration public ABI uses module `composer`. The canonical frame-orchestration public ABI uses module `composer`.
The `composer` module is a game profile surface. It is not inherited by
`System` profile apps as their public UI/composition API.
Canonical operations in v1 are: Canonical operations in v1 are:
- `composer.bind_scene(bank_id) -> (status)` - `composer.bind_scene(bank_id) -> (status)`