frame composer - abi adjustments
This commit is contained in:
parent
f4260d0cf4
commit
240fe65da7
@ -1,4 +1,4 @@
|
|||||||
{"type":"meta","next_id":{"DSC":27,"AGD":27,"DEC":15,"PLN":22,"LSN":31,"CLSN":1}}
|
{"type":"meta","next_id":{"DSC":28,"AGD":28,"DEC":16,"PLN":26,"LSN":31,"CLSN":1}}
|
||||||
{"type":"discussion","id":"DSC-0023","status":"done","ticket":"perf-full-migration-to-atomic-telemetry","title":"Agenda - [PERF] Full Migration to Atomic Telemetry","created_at":"2026-04-10","updated_at":"2026-04-10","tags":["perf","runtime","telemetry"],"agendas":[{"id":"AGD-0021","file":"workflow/agendas/AGD-0021-full-migration-to-atomic-telemetry.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}],"decisions":[{"id":"DEC-0008","file":"workflow/decisions/DEC-0008-full-migration-to-atomic-telemetry.md","status":"accepted","created_at":"2026-04-10","updated_at":"2026-04-10"}],"plans":[{"id":"PLN-0007","file":"workflow/plans/PLN-0007-full-migration-to-atomic-telemetry.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}],"lessons":[{"id":"LSN-0028","file":"lessons/DSC-0023-perf-full-migration-to-atomic-telemetry/LSN-0028-converging-to-single-atomic-telemetry-source.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}]}
|
{"type":"discussion","id":"DSC-0023","status":"done","ticket":"perf-full-migration-to-atomic-telemetry","title":"Agenda - [PERF] Full Migration to Atomic Telemetry","created_at":"2026-04-10","updated_at":"2026-04-10","tags":["perf","runtime","telemetry"],"agendas":[{"id":"AGD-0021","file":"workflow/agendas/AGD-0021-full-migration-to-atomic-telemetry.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}],"decisions":[{"id":"DEC-0008","file":"workflow/decisions/DEC-0008-full-migration-to-atomic-telemetry.md","status":"accepted","created_at":"2026-04-10","updated_at":"2026-04-10"}],"plans":[{"id":"PLN-0007","file":"workflow/plans/PLN-0007-full-migration-to-atomic-telemetry.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}],"lessons":[{"id":"LSN-0028","file":"lessons/DSC-0023-perf-full-migration-to-atomic-telemetry/LSN-0028-converging-to-single-atomic-telemetry-source.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}]}
|
||||||
{"type":"discussion","id":"DSC-0020","status":"done","ticket":"jenkins-gitea-integration","title":"Jenkins Gitea Integration and Relocation","created_at":"2026-04-07","updated_at":"2026-04-07","tags":["ci","jenkins","gitea"],"agendas":[{"id":"AGD-0018","file":"workflow/agendas/AGD-0018-jenkins-gitea-integration-and-relocation.md","status":"done","created_at":"2026-04-07","updated_at":"2026-04-07"}],"decisions":[{"id":"DEC-0003","file":"workflow/decisions/DEC-0003-jenkins-gitea-strategy.md","status":"accepted","created_at":"2026-04-07","updated_at":"2026-04-07"}],"plans":[{"id":"PLN-0003","file":"workflow/plans/PLN-0003-jenkins-gitea-execution.md","status":"done","created_at":"2026-04-07","updated_at":"2026-04-07"}],"lessons":[{"id":"LSN-0021","file":"lessons/DSC-0020-jenkins-gitea-integration/LSN-0021-jenkins-gitea-integration.md","status":"done","created_at":"2026-04-07","updated_at":"2026-04-07"}]}
|
{"type":"discussion","id":"DSC-0020","status":"done","ticket":"jenkins-gitea-integration","title":"Jenkins Gitea Integration and Relocation","created_at":"2026-04-07","updated_at":"2026-04-07","tags":["ci","jenkins","gitea"],"agendas":[{"id":"AGD-0018","file":"workflow/agendas/AGD-0018-jenkins-gitea-integration-and-relocation.md","status":"done","created_at":"2026-04-07","updated_at":"2026-04-07"}],"decisions":[{"id":"DEC-0003","file":"workflow/decisions/DEC-0003-jenkins-gitea-strategy.md","status":"accepted","created_at":"2026-04-07","updated_at":"2026-04-07"}],"plans":[{"id":"PLN-0003","file":"workflow/plans/PLN-0003-jenkins-gitea-execution.md","status":"done","created_at":"2026-04-07","updated_at":"2026-04-07"}],"lessons":[{"id":"LSN-0021","file":"lessons/DSC-0020-jenkins-gitea-integration/LSN-0021-jenkins-gitea-integration.md","status":"done","created_at":"2026-04-07","updated_at":"2026-04-07"}]}
|
||||||
{"type":"discussion","id":"DSC-0021","status":"done","ticket":"asset-entry-codec-enum-with-metadata","title":"Asset Entry Codec Enum Contract","created_at":"2026-04-09","updated_at":"2026-04-09","tags":["asset","runtime","codec","metadata"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0024","file":"lessons/DSC-0021-asset-entry-codec-enum-contract/LSN-0024-string-on-the-wire-enum-in-runtime.md","status":"done","created_at":"2026-04-09","updated_at":"2026-04-09"}]}
|
{"type":"discussion","id":"DSC-0021","status":"done","ticket":"asset-entry-codec-enum-with-metadata","title":"Asset Entry Codec Enum Contract","created_at":"2026-04-09","updated_at":"2026-04-09","tags":["asset","runtime","codec","metadata"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0024","file":"lessons/DSC-0021-asset-entry-codec-enum-contract/LSN-0024-string-on-the-wire-enum-in-runtime.md","status":"done","created_at":"2026-04-09","updated_at":"2026-04-09"}]}
|
||||||
@ -19,6 +19,7 @@
|
|||||||
{"type":"discussion","id":"DSC-0024","status":"done","ticket":"generic-memory-bank-slot-contract","title":"Agenda - Generic Memory Bank Slot Contract","created_at":"2026-04-10","updated_at":"2026-04-10","tags":["runtime","asset","memory-bank","slots","host"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0029","file":"lessons/DSC-0024-generic-memory-bank-slot-contract/LSN-0029-slot-first-bank-telemetry-belongs-in-asset-manager.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}]}
|
{"type":"discussion","id":"DSC-0024","status":"done","ticket":"generic-memory-bank-slot-contract","title":"Agenda - Generic Memory Bank Slot Contract","created_at":"2026-04-10","updated_at":"2026-04-10","tags":["runtime","asset","memory-bank","slots","host"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0029","file":"lessons/DSC-0024-generic-memory-bank-slot-contract/LSN-0029-slot-first-bank-telemetry-belongs-in-asset-manager.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}]}
|
||||||
{"type":"discussion","id":"DSC-0025","status":"done","ticket":"scene-bank-and-viewport-cache-refactor","title":"Scene Bank and Viewport Cache Refactor","created_at":"2026-04-11","updated_at":"2026-04-14","tags":["gfx","tilemap","runtime","render"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0030","file":"lessons/DSC-0025-scene-bank-and-viewport-cache-refactor/LSN-0030-canonical-scene-cache-and-resolver-split.md","status":"done","created_at":"2026-04-14","updated_at":"2026-04-14"}]}
|
{"type":"discussion","id":"DSC-0025","status":"done","ticket":"scene-bank-and-viewport-cache-refactor","title":"Scene Bank and Viewport Cache Refactor","created_at":"2026-04-11","updated_at":"2026-04-14","tags":["gfx","tilemap","runtime","render"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0030","file":"lessons/DSC-0025-scene-bank-and-viewport-cache-refactor/LSN-0030-canonical-scene-cache-and-resolver-split.md","status":"done","created_at":"2026-04-14","updated_at":"2026-04-14"}]}
|
||||||
{"type":"discussion","id":"DSC-0026","status":"open","ticket":"render-all-scene-cache-and-camera-integration","title":"Integrate render_all with Scene Cache and Camera","created_at":"2026-04-14","updated_at":"2026-04-15","tags":["gfx","runtime","render","camera","scene"],"agendas":[{"id":"AGD-0026","file":"workflow/agendas/AGD-0026-render-all-scene-cache-and-camera-integration.md","status":"accepted","created_at":"2026-04-14","updated_at":"2026-04-15"}],"decisions":[{"id":"DEC-0014","file":"workflow/decisions/DEC-0014-frame-composer-render-integration.md","status":"accepted","created_at":"2026-04-14","updated_at":"2026-04-15","ref_agenda":"AGD-0026"}],"plans":[{"id":"PLN-0017","file":"workflow/plans/PLN-0017-frame-composer-core-and-hardware-ownership.md","status":"accepted","created_at":"2026-04-14","updated_at":"2026-04-15","ref_decisions":["DEC-0014"]},{"id":"PLN-0018","file":"workflow/plans/PLN-0018-sprite-controller-and-frame-emission-model.md","status":"accepted","created_at":"2026-04-14","updated_at":"2026-04-14","ref_decisions":["DEC-0014"]},{"id":"PLN-0019","file":"workflow/plans/PLN-0019-scene-binding-camera-and-scene-status.md","status":"accepted","created_at":"2026-04-14","updated_at":"2026-04-15","ref_decisions":["DEC-0014"]},{"id":"PLN-0020","file":"workflow/plans/PLN-0020-cache-refresh-and-render-frame-path.md","status":"accepted","created_at":"2026-04-14","updated_at":"2026-04-15","ref_decisions":["DEC-0014"]},{"id":"PLN-0021","file":"workflow/plans/PLN-0021-service-retirement-callsite-migration-and-regression.md","status":"accepted","created_at":"2026-04-14","updated_at":"2026-04-15","ref_decisions":["DEC-0014"]}],"lessons":[]}
|
{"type":"discussion","id":"DSC-0026","status":"open","ticket":"render-all-scene-cache-and-camera-integration","title":"Integrate render_all with Scene Cache and Camera","created_at":"2026-04-14","updated_at":"2026-04-15","tags":["gfx","runtime","render","camera","scene"],"agendas":[{"id":"AGD-0026","file":"workflow/agendas/AGD-0026-render-all-scene-cache-and-camera-integration.md","status":"accepted","created_at":"2026-04-14","updated_at":"2026-04-15"}],"decisions":[{"id":"DEC-0014","file":"workflow/decisions/DEC-0014-frame-composer-render-integration.md","status":"accepted","created_at":"2026-04-14","updated_at":"2026-04-15","ref_agenda":"AGD-0026"}],"plans":[{"id":"PLN-0017","file":"workflow/plans/PLN-0017-frame-composer-core-and-hardware-ownership.md","status":"accepted","created_at":"2026-04-14","updated_at":"2026-04-15","ref_decisions":["DEC-0014"]},{"id":"PLN-0018","file":"workflow/plans/PLN-0018-sprite-controller-and-frame-emission-model.md","status":"accepted","created_at":"2026-04-14","updated_at":"2026-04-14","ref_decisions":["DEC-0014"]},{"id":"PLN-0019","file":"workflow/plans/PLN-0019-scene-binding-camera-and-scene-status.md","status":"accepted","created_at":"2026-04-14","updated_at":"2026-04-15","ref_decisions":["DEC-0014"]},{"id":"PLN-0020","file":"workflow/plans/PLN-0020-cache-refresh-and-render-frame-path.md","status":"accepted","created_at":"2026-04-14","updated_at":"2026-04-15","ref_decisions":["DEC-0014"]},{"id":"PLN-0021","file":"workflow/plans/PLN-0021-service-retirement-callsite-migration-and-regression.md","status":"accepted","created_at":"2026-04-14","updated_at":"2026-04-15","ref_decisions":["DEC-0014"]}],"lessons":[]}
|
||||||
|
{"type":"discussion","id":"DSC-0027","status":"open","ticket":"frame-composer-public-syscall-surface","title":"Agenda - FrameComposer Public Syscall Surface","created_at":"2026-04-17","updated_at":"2026-04-17","tags":["gfx","runtime","syscall","abi","frame-composer","scene","camera","sprites"],"agendas":[{"id":"AGD-0027","file":"workflow/agendas/AGD-0027-frame-composer-public-syscall-surface.md","status":"accepted","created_at":"2026-04-17","updated_at":"2026-04-17"}],"decisions":[{"id":"DEC-0015","file":"workflow/decisions/DEC-0015-frame-composer-public-syscall-surface.md","status":"accepted","created_at":"2026-04-17","updated_at":"2026-04-17","ref_agenda":"AGD-0027"}],"plans":[{"id":"PLN-0022","file":"workflow/plans/PLN-0022-composer-syscall-domain-and-spec-propagation.md","status":"accepted","created_at":"2026-04-17","updated_at":"2026-04-17","ref_decisions":["DEC-0015"]},{"id":"PLN-0023","file":"workflow/plans/PLN-0023-composer-runtime-dispatch-and-legacy-removal.md","status":"accepted","created_at":"2026-04-17","updated_at":"2026-04-17","ref_decisions":["DEC-0015"]},{"id":"PLN-0024","file":"workflow/plans/PLN-0024-composer-cartridge-tooling-and-regression-migration.md","status":"accepted","created_at":"2026-04-17","updated_at":"2026-04-17","ref_decisions":["DEC-0015"]},{"id":"PLN-0025","file":"workflow/plans/PLN-0025-final-ci-validation-and-polish.md","status":"accepted","created_at":"2026-04-17","updated_at":"2026-04-17","ref_decisions":["DEC-0015"]}],"lessons":[]}
|
||||||
{"type":"discussion","id":"DSC-0014","status":"open","ticket":"perf-vm-allocation-and-copy-pressure","title":"Agenda - [PERF] VM Allocation and Copy Pressure","created_at":"2026-03-27","updated_at":"2026-03-27","tags":[],"agendas":[{"id":"AGD-0013","file":"workflow/agendas/AGD-0013-perf-vm-allocation-and-copy-pressure.md","status":"open","created_at":"2026-03-27","updated_at":"2026-03-27"}],"decisions":[],"plans":[],"lessons":[]}
|
{"type":"discussion","id":"DSC-0014","status":"open","ticket":"perf-vm-allocation-and-copy-pressure","title":"Agenda - [PERF] VM Allocation and Copy Pressure","created_at":"2026-03-27","updated_at":"2026-03-27","tags":[],"agendas":[{"id":"AGD-0013","file":"workflow/agendas/AGD-0013-perf-vm-allocation-and-copy-pressure.md","status":"open","created_at":"2026-03-27","updated_at":"2026-03-27"}],"decisions":[],"plans":[],"lessons":[]}
|
||||||
{"type":"discussion","id":"DSC-0015","status":"open","ticket":"perf-cartridge-boot-and-program-ownership","title":"Agenda - [PERF] Cartridge Boot and Program Ownership","created_at":"2026-03-27","updated_at":"2026-03-27","tags":[],"agendas":[{"id":"AGD-0014","file":"workflow/agendas/AGD-0014-perf-cartridge-boot-and-program-ownership.md","status":"open","created_at":"2026-03-27","updated_at":"2026-03-27"}],"decisions":[],"plans":[],"lessons":[]}
|
{"type":"discussion","id":"DSC-0015","status":"open","ticket":"perf-cartridge-boot-and-program-ownership","title":"Agenda - [PERF] Cartridge Boot and Program Ownership","created_at":"2026-03-27","updated_at":"2026-03-27","tags":[],"agendas":[{"id":"AGD-0014","file":"workflow/agendas/AGD-0014-perf-cartridge-boot-and-program-ownership.md","status":"open","created_at":"2026-03-27","updated_at":"2026-03-27"}],"decisions":[],"plans":[],"lessons":[]}
|
||||||
{"type":"discussion","id":"DSC-0016","status":"done","ticket":"tilemap-empty-cell-vs-tile-id-zero","title":"Tilemap Empty Cell vs Tile ID Zero","created_at":"2026-03-27","updated_at":"2026-04-09","tags":[],"agendas":[{"id":"AGD-0015","file":"workflow/agendas/AGD-0015-tilemap-empty-cell-vs-tile-id-zero.md","status":"done","created_at":"2026-03-27","updated_at":"2026-04-09"}],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0022","file":"lessons/DSC-0016-tilemap-empty-cell-semantics/LSN-0022-tilemap-empty-cell-convergence.md","status":"done","created_at":"2026-04-09","updated_at":"2026-04-09"}]}
|
{"type":"discussion","id":"DSC-0016","status":"done","ticket":"tilemap-empty-cell-vs-tile-id-zero","title":"Tilemap Empty Cell vs Tile ID Zero","created_at":"2026-03-27","updated_at":"2026-04-09","tags":[],"agendas":[{"id":"AGD-0015","file":"workflow/agendas/AGD-0015-tilemap-empty-cell-vs-tile-id-zero.md","status":"done","created_at":"2026-03-27","updated_at":"2026-04-09"}],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0022","file":"lessons/DSC-0016-tilemap-empty-cell-semantics/LSN-0022-tilemap-empty-cell-convergence.md","status":"done","created_at":"2026-04-09","updated_at":"2026-04-09"}]}
|
||||||
|
|||||||
@ -0,0 +1,214 @@
|
|||||||
|
---
|
||||||
|
id: AGD-0027
|
||||||
|
ticket: frame-composer-public-syscall-surface
|
||||||
|
title: Agenda - FrameComposer Public Syscall Surface
|
||||||
|
status: accepted
|
||||||
|
created: 2026-04-17
|
||||||
|
updated: 2026-04-17
|
||||||
|
tags: [gfx, runtime, syscall, abi, frame-composer, scene, camera, sprites]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Contexto
|
||||||
|
|
||||||
|
`DEC-0014` e os planos `PLN-0017` a `PLN-0021` fecharam a migração interna do pipeline de frame para `FrameComposer`:
|
||||||
|
|
||||||
|
- `FrameComposer` virou o orquestrador canônico do frame;
|
||||||
|
- `Hardware` passou a agregá-lo ao lado de `Gfx`;
|
||||||
|
- scene, camera, cache, resolver e sprite emission migraram para ownership interno dele;
|
||||||
|
- o frame loop do runtime passou a renderizar via `FrameComposer.render_frame()`.
|
||||||
|
|
||||||
|
Isso resolveu a base operacional interna, mas não fechou a superfície pública equivalente para a VM. A ABI pública ainda expõe apenas o contrato legado de `gfx.set_sprite(...)`, enquanto `bind_scene(...)` e `set_camera(...)` existem apenas como APIs internas do driver.
|
||||||
|
|
||||||
|
Na prática, hoje temos uma assimetria:
|
||||||
|
|
||||||
|
- a base canônica do frame está em `FrameComposer`;
|
||||||
|
- mas a ABI pública ainda não trata `FrameComposer` como serviço canônico para scene, camera e sprites.
|
||||||
|
|
||||||
|
Essa lacuna impede a migração do restante da stack e também impede um stress cartridge que atravesse de verdade o pipeline novo por syscall pública.
|
||||||
|
|
||||||
|
## Problema
|
||||||
|
|
||||||
|
Precisamos definir a nova superfície pública de syscall para o pipeline canônico de `FrameComposer` sem reabrir a decisão já aceita sobre ownership interno do frame.
|
||||||
|
|
||||||
|
O problema concreto não é “adicionar 2 ou 3 syscalls”. Precisamos decidir:
|
||||||
|
|
||||||
|
- quais operações de `FrameComposer` viram ABI pública agora;
|
||||||
|
- se `gfx.set_sprite(...)` continua como shim legado ou perde status canônico;
|
||||||
|
- qual é o contrato mínimo de scene/camera que a VM pode observar/controlar;
|
||||||
|
- como nomear e versionar essa superfície pública sem criar um segundo modelo canônico concorrente;
|
||||||
|
- qual é a estratégia de transição para cartridge, runtime tests e stress tests;
|
||||||
|
- como propagar essa mudança para a spec canônica e, se necessário, para contratos de ABI e `ISA_CORE`.
|
||||||
|
|
||||||
|
## Pontos Criticos
|
||||||
|
|
||||||
|
- `DEC-0014` já fechou `FrameComposer` como base canônica interna; esta agenda não deve reabrir isso.
|
||||||
|
- A ABI pública atual ainda expõe `gfx.set_sprite(...)` com semântica herdada de índice/slot, mesmo que a implementação interna já use frame emission.
|
||||||
|
- `bind_scene(scene_bank_id)` e `set_camera(x, y)` já existem no driver, mas ainda não existem como syscalls públicas.
|
||||||
|
- Se a nova ABI expuser demais logo de início, vamos congelar cedo demais detalhes que ainda não provaram valor operacional.
|
||||||
|
- Se a nova ABI expuser de menos, manteremos um modelo híbrido por tempo demais:
|
||||||
|
- canônico internamente via `FrameComposer`;
|
||||||
|
- legado externamente via `Gfx`/`set_sprite`.
|
||||||
|
- Precisamos decidir se o namespace público continua em `gfx.*` por estabilidade do domínio, ou se devemos introduzir algo como `frame.*`.
|
||||||
|
- A transição precisa preservar compatibilidade suficiente para não quebrar cartridges e testes existentes antes da migração do restante.
|
||||||
|
- O contrato de sprite precisa deixar claro se o chamador ainda informa índice, se informa `layer`, e se `active` continua existindo na superfície pública.
|
||||||
|
- A mudança não pode ficar só em código/runtime; a spec canônica precisa ser atualizada para refletir o novo serviço público.
|
||||||
|
- Se o contrato público afetar superfícies documentadas de ABI ou o material de `ISA_CORE`, essa propagação precisa ser tratada como parte da mesma thread, não como follow-up solto.
|
||||||
|
|
||||||
|
## Opcoes
|
||||||
|
|
||||||
|
### Opcao 1 - Expor um núcleo mínimo canônico em `gfx.*`
|
||||||
|
|
||||||
|
**Como seria:**
|
||||||
|
Adicionar apenas a superfície mínima para a VM controlar o pipeline novo:
|
||||||
|
|
||||||
|
- `gfx.bind_scene(bank_id)`
|
||||||
|
- `gfx.unbind_scene()`
|
||||||
|
- `gfx.set_camera(x, y)`
|
||||||
|
- `gfx.emit_sprite(...)`
|
||||||
|
|
||||||
|
`gfx.set_sprite(...)` permaneceria por um período como shim legado de compatibilidade.
|
||||||
|
|
||||||
|
**Vantagens:**
|
||||||
|
- fecha rapidamente a lacuna operacional;
|
||||||
|
- habilita stress real do pipeline novo;
|
||||||
|
- reduz o tempo de convivência entre modelo canônico e legado;
|
||||||
|
- mantém o domínio público em `gfx`, evitando churn de namespace.
|
||||||
|
|
||||||
|
**Desvantagens:**
|
||||||
|
- introduz ABI nova que precisará de migração coordenada;
|
||||||
|
- exige definir `emit_sprite(...)` com cuidado para não herdar sem querer o modelo de slot.
|
||||||
|
|
||||||
|
### Opcao 2 - Expor scene/camera agora e adiar o contrato novo de sprite
|
||||||
|
|
||||||
|
**Como seria:**
|
||||||
|
Publicar apenas:
|
||||||
|
|
||||||
|
- `gfx.bind_scene(bank_id)`
|
||||||
|
- `gfx.unbind_scene()`
|
||||||
|
- `gfx.set_camera(x, y)`
|
||||||
|
|
||||||
|
Sprites continuariam publicamente via `gfx.set_sprite(...)` até uma segunda fase.
|
||||||
|
|
||||||
|
**Vantagens:**
|
||||||
|
- menor mudança imediata de ABI;
|
||||||
|
- desbloqueia o stress do world path e da câmera;
|
||||||
|
- reduz o volume inicial da migração pública.
|
||||||
|
|
||||||
|
**Desvantagens:**
|
||||||
|
- mantém dois modelos públicos de sprite por mais tempo;
|
||||||
|
- prolonga a semântica de compatibilidade do syscall legado;
|
||||||
|
- adia exatamente uma das partes centrais da migração para `FrameComposer`.
|
||||||
|
|
||||||
|
### Opcao 3 - Criar um novo namespace público separado, como `composer.*`
|
||||||
|
|
||||||
|
**Como seria:**
|
||||||
|
O pipeline novo ganha syscalls em um domínio separado, por exemplo:
|
||||||
|
|
||||||
|
- `composer.bind_scene`
|
||||||
|
- `composer.unbind_scene`
|
||||||
|
- `composer.set_camera`
|
||||||
|
- `composer.emit_sprite`
|
||||||
|
|
||||||
|
`gfx.*` ficaria como superfície legacy/low-level.
|
||||||
|
|
||||||
|
**Vantagens:**
|
||||||
|
- deixa explícita a mudança de serviço canônico;
|
||||||
|
- evita sobrecarregar semanticamente `gfx`.
|
||||||
|
|
||||||
|
**Desvantagens:**
|
||||||
|
- adiciona churn conceitual e de nomenclatura;
|
||||||
|
- fragmenta demais a superfície pública neste momento;
|
||||||
|
- cria um custo de transição maior sem benefício operacional evidente.
|
||||||
|
|
||||||
|
## Sugestao / Recomendacao
|
||||||
|
|
||||||
|
Seguir com a **Opcao 3**.
|
||||||
|
|
||||||
|
Direção recomendada:
|
||||||
|
|
||||||
|
- a superfície pública canônica deve migrar para o domínio `composer.*`;
|
||||||
|
- `FrameComposer` vira a base canônica também na ABI pública, com namespace próprio em vez de continuar semanticamente preso a `gfx.*`;
|
||||||
|
- o núcleo mínimo público deve ser:
|
||||||
|
- `composer.bind_scene(bank_id) -> status`
|
||||||
|
- `composer.unbind_scene()`
|
||||||
|
- `composer.set_camera(x, y)`
|
||||||
|
- `composer.emit_sprite(...) -> status`
|
||||||
|
- `gfx.set_sprite(...)` deve morrer e ser removido completamente do contrato público.
|
||||||
|
|
||||||
|
Para sprites, a recomendação provisória é:
|
||||||
|
|
||||||
|
- a nova ABI pública não deve exigir índice explícito;
|
||||||
|
- `composer.emit_sprite(...)` deve receber o payload completo necessário para o frame:
|
||||||
|
- `glyph_id`
|
||||||
|
- `palette_id`
|
||||||
|
- `x`
|
||||||
|
- `y`
|
||||||
|
- `layer`
|
||||||
|
- `bank_id`
|
||||||
|
- `flip_x`
|
||||||
|
- `flip_y`
|
||||||
|
- `priority`
|
||||||
|
- a ABI pode futuramente agrupar esse payload se isso melhorar ergonomia, mas o contrato mínimo deve nascer completo;
|
||||||
|
- `active` não deve continuar no contrato canônico novo;
|
||||||
|
- overflow continua sendo ignorado com status/telemetria adequada, sem trapar o runtime.
|
||||||
|
|
||||||
|
Para scene/camera, a recomendação provisória é:
|
||||||
|
|
||||||
|
- manter o contrato mínimo já aceito internamente;
|
||||||
|
- `bind_scene` por bank id;
|
||||||
|
- `unbind_scene` explícito;
|
||||||
|
- `set_camera(x, y)` em pixel space com top-left viewport.
|
||||||
|
- `bind_scene(...)`, `unbind_scene(...)` e `emit_sprite(...)` devem usar `ComposerOpStatus` como retorno operacional canônico.
|
||||||
|
|
||||||
|
## Perguntas em Aberto
|
||||||
|
|
||||||
|
- Resolvido:
|
||||||
|
- o nome público canônico de sprite será `composer.emit_sprite(...)`;
|
||||||
|
- o syscall novo de sprite nasce completo com `glyph_id`, `palette_id`, `x`, `y`, `layer`, `bank_id`, `flip_x`, `flip_y`, `priority`;
|
||||||
|
- `gfx.set_sprite(...)` deve morrer e ser removido completamente;
|
||||||
|
- não haverá leitura de estado nesta primeira fase;
|
||||||
|
- `bind_scene(...)`, `unbind_scene(...)` e `emit_sprite(...)` usarão `ComposerOpStatus`;
|
||||||
|
- A ABI nova precisa expor refresh explícito, ou isso deve continuar totalmente interno ao `FrameComposer`?
|
||||||
|
- Resolvido:
|
||||||
|
- a ABI nova não deve expor refresh explícito;
|
||||||
|
- o domínio público canônico será `composer.*`, não `gfx.*`.
|
||||||
|
|
||||||
|
## Criterio para Encerrar
|
||||||
|
|
||||||
|
Esta agenda pode ser encerrada quando houver acordo explícito sobre:
|
||||||
|
|
||||||
|
- a lista mínima de syscalls públicas canônicas do `FrameComposer`;
|
||||||
|
- o nome canônico da operação pública de sprite;
|
||||||
|
- a remoção completa de `gfx.set_sprite(...)` do contrato público;
|
||||||
|
- o formato de retorno/status das novas operações;
|
||||||
|
- a estratégia de transição necessária para decisão, plano e migração do restante da stack.
|
||||||
|
|
||||||
|
## Resolucao em Andamento
|
||||||
|
|
||||||
|
Direção atualmente acordada nesta agenda:
|
||||||
|
|
||||||
|
- o namespace público canônico será `composer.*`;
|
||||||
|
- o núcleo mínimo inicial será:
|
||||||
|
- `composer.bind_scene(bank_id) -> ComposerOpStatus`
|
||||||
|
- `composer.unbind_scene() -> ComposerOpStatus`
|
||||||
|
- `composer.set_camera(x, y)`
|
||||||
|
- `composer.emit_sprite(glyph_id, palette_id, x, y, layer, bank_id, flip_x, flip_y, priority) -> ComposerOpStatus`
|
||||||
|
- não haverá introspecção pública nesta primeira fase;
|
||||||
|
- refresh/cache policy continua interno ao `FrameComposer`;
|
||||||
|
- `gfx.set_sprite(...)` não terá caminho de compatibilidade e deve ser removido.
|
||||||
|
|
||||||
|
## Resolucao
|
||||||
|
|
||||||
|
Esta agenda fica aceita com os seguintes pontos fechados:
|
||||||
|
|
||||||
|
- o namespace público canônico do serviço será `composer.*`;
|
||||||
|
- a superfície mínima inicial será:
|
||||||
|
- `composer.bind_scene(bank_id) -> ComposerOpStatus`
|
||||||
|
- `composer.unbind_scene() -> ComposerOpStatus`
|
||||||
|
- `composer.set_camera(x, y)`
|
||||||
|
- `composer.emit_sprite(glyph_id, palette_id, x, y, layer, bank_id, flip_x, flip_y, priority) -> ComposerOpStatus`
|
||||||
|
- não haverá introspecção pública nesta primeira fase;
|
||||||
|
- não haverá refresh/cache policy público;
|
||||||
|
- `gfx.set_sprite(...)` deve ser removido completamente, sem shim de compatibilidade;
|
||||||
|
- a transição deve introduzir `composer.*` e remover `gfx.set_sprite(...)` na mesma thread de migração, com atualização coordenada de bytecode, cartridges, tests e runtime;
|
||||||
|
- a mesma thread deve atualizar a spec canônica do assunto e propagar a mudança para contratos de ABI e `ISA_CORE` quando essas superfícies forem impactadas pelo novo serviço público.
|
||||||
@ -0,0 +1,166 @@
|
|||||||
|
---
|
||||||
|
id: DEC-0015
|
||||||
|
ticket: frame-composer-public-syscall-surface
|
||||||
|
title: FrameComposer Public Syscall Surface
|
||||||
|
status: accepted
|
||||||
|
created: 2026-04-17
|
||||||
|
accepted: 2026-04-17
|
||||||
|
agenda: AGD-0027
|
||||||
|
plans: [PLN-0022, PLN-0023, PLN-0024, PLN-0025]
|
||||||
|
tags: [gfx, runtime, syscall, abi, frame-composer, scene, camera, sprites]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Accepted.
|
||||||
|
|
||||||
|
## Contexto
|
||||||
|
|
||||||
|
`DEC-0014` locked `FrameComposer` as the canonical internal frame orchestration service and `PLN-0017` through `PLN-0021` completed that internal migration path. `Hardware` now owns `FrameComposer`, the runtime renders through `FrameComposer.render_frame()`, and scene/camera/cache/resolver/sprite ownership no longer belongs canonically to `Gfx`.
|
||||||
|
|
||||||
|
That migration did not define the equivalent public syscall contract for VM code. The public ABI still exposed legacy `gfx`-domain sprite control while the canonical scene/camera operations existed only as internal driver APIs.
|
||||||
|
|
||||||
|
This decision closes that public ABI gap without reopening the already accepted internal ownership model.
|
||||||
|
|
||||||
|
## Decisao
|
||||||
|
|
||||||
|
The canonical public syscall surface for frame orchestration SHALL move to the `composer.*` namespace.
|
||||||
|
|
||||||
|
Normatively:
|
||||||
|
|
||||||
|
- The canonical public service domain for `FrameComposer` operations SHALL be `composer`.
|
||||||
|
- The initial canonical syscall set SHALL be:
|
||||||
|
- `composer.bind_scene(bank_id) -> ComposerOpStatus`
|
||||||
|
- `composer.unbind_scene() -> ComposerOpStatus`
|
||||||
|
- `composer.set_camera(x, y)`
|
||||||
|
- `composer.emit_sprite(glyph_id, palette_id, x, y, layer, bank_id, flip_x, flip_y, priority) -> ComposerOpStatus`
|
||||||
|
- `composer.emit_sprite(...)` SHALL be the canonical public sprite submission path.
|
||||||
|
- `composer.emit_sprite(...)` MUST NOT require a caller-provided sprite index.
|
||||||
|
- `composer.emit_sprite(...)` MUST carry `layer` and `priority`.
|
||||||
|
- `composer.emit_sprite(...)` MUST NOT expose `active` as part of the canonical contract.
|
||||||
|
- `composer.bind_scene(...)`, `composer.unbind_scene()`, and `composer.emit_sprite(...)` SHALL return `ComposerOpStatus`.
|
||||||
|
- `composer.set_camera(x, y)` SHALL keep the minimal V1 camera contract already accepted by `DEC-0014`:
|
||||||
|
- `x` and `y` are `i32` pixel coordinates;
|
||||||
|
- they represent the top-left viewport origin in world space.
|
||||||
|
- The public ABI MUST NOT expose cache refresh policy or explicit refresh controls.
|
||||||
|
- The public ABI MUST NOT expose scene/camera introspection in this first phase.
|
||||||
|
- `gfx.set_sprite(...)` MUST be removed completely from the public contract.
|
||||||
|
- No compatibility shim for `gfx.set_sprite(...)` SHALL remain as part of the canonical migration target.
|
||||||
|
- Introduction of `composer.*` and removal of `gfx.set_sprite(...)` SHALL be executed in the same migration thread.
|
||||||
|
|
||||||
|
## Rationale
|
||||||
|
|
||||||
|
The public ABI must reflect the accepted ownership model rather than preserve a misleading legacy shape.
|
||||||
|
|
||||||
|
Keeping the canonical public surface under `gfx.*` would continue to tie orchestration semantics to the wrong service boundary. The new namespace makes the ownership change explicit:
|
||||||
|
|
||||||
|
- `Gfx` is the visual backend;
|
||||||
|
- `FrameComposer` is the frame orchestration service.
|
||||||
|
|
||||||
|
Removing `gfx.set_sprite(...)` completely avoids prolonging a dual public sprite model. A compatibility shim would preserve legacy slot/index semantics in the public contract after those semantics had already ceased to be canonical internally.
|
||||||
|
|
||||||
|
Returning `ComposerOpStatus` for operational mutating calls preserves status-first behavior while keeping the public contract aligned with the new service boundary. Reusing `GfxOpStatus` would leak backend-domain semantics into orchestration-domain syscalls after that separation had already been made explicit.
|
||||||
|
|
||||||
|
Deferring introspection and explicit refresh controls keeps the first public ABI focused on control, not diagnostics or internal policy leakage.
|
||||||
|
|
||||||
|
## Invariantes / Contrato
|
||||||
|
|
||||||
|
### 1. Namespace
|
||||||
|
|
||||||
|
- Public frame-orchestration syscalls MUST live under `composer.*`.
|
||||||
|
- `composer.*` SHALL be treated as the canonical public orchestration surface.
|
||||||
|
- `gfx.*` SHALL NOT remain the canonical public orchestration namespace for scene/camera/sprite submission.
|
||||||
|
|
||||||
|
### 2. Scene Control
|
||||||
|
|
||||||
|
- `composer.bind_scene(bank_id)` MUST bind by scene bank id.
|
||||||
|
- Binding semantics MUST remain aligned with `DEC-0014`:
|
||||||
|
- scene resolution through the scene bank pool;
|
||||||
|
- explicit bind/unbind lifecycle;
|
||||||
|
- no implicit per-frame rebinding.
|
||||||
|
- `composer.unbind_scene()` MUST leave no-scene rendering valid.
|
||||||
|
- `ComposerOpStatus` SHALL be the canonical operational status family for composer-domain mutating syscalls.
|
||||||
|
|
||||||
|
### 3. Camera
|
||||||
|
|
||||||
|
- `composer.set_camera(x, y)` MUST remain the minimal V1 camera API.
|
||||||
|
- Camera follow, smoothing, shake, transitions, and readback are OUT OF SCOPE for this decision.
|
||||||
|
|
||||||
|
### 4. Sprite Submission
|
||||||
|
|
||||||
|
- `composer.emit_sprite(...)` MUST be frame-emission based.
|
||||||
|
- The caller MUST NOT provide sprite slot/index information.
|
||||||
|
- The public payload MUST include:
|
||||||
|
- `glyph_id`
|
||||||
|
- `palette_id`
|
||||||
|
- `x`
|
||||||
|
- `y`
|
||||||
|
- `layer`
|
||||||
|
- `bank_id`
|
||||||
|
- `flip_x`
|
||||||
|
- `flip_y`
|
||||||
|
- `priority`
|
||||||
|
- The canonical public sprite contract MUST NOT include `active`.
|
||||||
|
- Overflow behavior SHALL remain aligned with `DEC-0014`:
|
||||||
|
- excess sprites are ignored;
|
||||||
|
- overflow is not a hard VM fault in V1.
|
||||||
|
|
||||||
|
### 5. Non-Goals for V1 Public ABI
|
||||||
|
|
||||||
|
- No public refresh/invalidate syscalls.
|
||||||
|
- No public cache inspection syscalls.
|
||||||
|
- No public `scene_status()` syscall.
|
||||||
|
- No public `get_camera()` syscall.
|
||||||
|
|
||||||
|
### 6. Migration Contract
|
||||||
|
|
||||||
|
- Migration MUST update:
|
||||||
|
- syscall registry and ABI resolution;
|
||||||
|
- runtime dispatch;
|
||||||
|
- bytecode/cartridge declarations;
|
||||||
|
- tests;
|
||||||
|
- stress cartridges and related tooling where applicable.
|
||||||
|
- Migration MUST NOT leave `gfx.set_sprite(...)` as a supported public fallback after the new contract lands.
|
||||||
|
|
||||||
|
## Impactos
|
||||||
|
|
||||||
|
### HAL
|
||||||
|
|
||||||
|
- The syscall enum, registry, metadata, and resolver will need a new `composer` domain surface.
|
||||||
|
- `gfx.set_sprite(...)` must be removed from the public ABI contract.
|
||||||
|
- A new `ComposerOpStatus` contract will need to be introduced for composer-domain operational returns.
|
||||||
|
|
||||||
|
### Runtime / VM
|
||||||
|
|
||||||
|
- Runtime dispatch must route public scene/camera/sprite orchestration through `FrameComposer`.
|
||||||
|
- Existing bytecode declarations and cartridges that rely on `gfx.set_sprite(...)` will need coordinated migration.
|
||||||
|
|
||||||
|
### Spec / ABI / ISA_CORE
|
||||||
|
|
||||||
|
- The canonical spec for the public VM-facing graphics/composition surface must be updated to reflect `composer.*`.
|
||||||
|
- ABI-facing documentation and contracts must be updated wherever syscall domain, names, arguments, or return semantics are specified.
|
||||||
|
- `ISA_CORE` must be updated if and where it normatively references the public syscall surface affected by this decision.
|
||||||
|
|
||||||
|
### Drivers / Hardware
|
||||||
|
|
||||||
|
- `FrameComposer` already has the required internal base; execution work will focus on public ABI exposure rather than internal ownership redesign.
|
||||||
|
|
||||||
|
### Tooling / Stress
|
||||||
|
|
||||||
|
- Stress cartridges and bytecode generators can only exercise the canonical frame path publicly after `composer.*` exists.
|
||||||
|
|
||||||
|
## Referencias
|
||||||
|
|
||||||
|
- [AGD-0027-frame-composer-public-syscall-surface.md](/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/runtime/discussion/workflow/agendas/AGD-0027-frame-composer-public-syscall-surface.md)
|
||||||
|
- [DEC-0014-frame-composer-render-integration.md](/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/runtime/discussion/workflow/decisions/DEC-0014-frame-composer-render-integration.md)
|
||||||
|
|
||||||
|
## Propagacao Necessaria
|
||||||
|
|
||||||
|
- A new implementation plan MUST be created from this decision before code changes.
|
||||||
|
- The plan MUST cover ABI introduction, legacy syscall removal, cartridge/test migration, regression coverage, and canonical spec propagation.
|
||||||
|
- The plan MUST explicitly assess and update ABI and `ISA_CORE` artifacts where this decision changes documented public behavior.
|
||||||
|
- Stress tooling SHOULD be updated as part of the migration thread so the public ABI can exercise the canonical frame path end-to-end.
|
||||||
|
|
||||||
|
## Revision Log
|
||||||
|
|
||||||
|
- 2026-04-17: Initial accepted decision from `AGD-0027`.
|
||||||
@ -0,0 +1,122 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0022
|
||||||
|
ticket: frame-composer-public-syscall-surface
|
||||||
|
title: Plan - Composer Syscall Domain and Spec Propagation
|
||||||
|
status: accepted
|
||||||
|
created: 2026-04-17
|
||||||
|
completed:
|
||||||
|
tags: [gfx, runtime, syscall, abi, spec, isa-core, frame-composer]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Objective
|
||||||
|
|
||||||
|
Introduce the canonical `composer.*` syscall domain, define `ComposerOpStatus`, and propagate the new public contract through the canonical spec, ABI documentation, and `ISA_CORE` artifacts where affected.
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
`DEC-0015` locks the public orchestration surface on `composer.*`, requires `ComposerOpStatus` for mutating composer-domain calls, and requires propagation beyond code into canonical spec, ABI-facing documentation, and `ISA_CORE` where the public syscall surface is described normatively.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
### Included
|
||||||
|
- add the `composer` syscall domain and ids
|
||||||
|
- define `ComposerOpStatus`
|
||||||
|
- remove `gfx.set_sprite(...)` from the public ABI contract
|
||||||
|
- update canonical spec documentation for the new public surface
|
||||||
|
- update ABI-facing documentation and `ISA_CORE` wherever the public syscall contract is described
|
||||||
|
|
||||||
|
### Excluded
|
||||||
|
- runtime dispatch implementation
|
||||||
|
- cartridge and stress program migration
|
||||||
|
- final repository-wide CI execution
|
||||||
|
|
||||||
|
## Execution Steps
|
||||||
|
|
||||||
|
### Step 1 - Define the public `composer` syscall contract
|
||||||
|
|
||||||
|
**What:**
|
||||||
|
Add the new canonical public syscall surface to the HAL syscall contract.
|
||||||
|
|
||||||
|
**How:**
|
||||||
|
- Extend the syscall enum, registry, metadata, and resolver with a new `composer` domain.
|
||||||
|
- Allocate explicit syscall ids for:
|
||||||
|
- `composer.bind_scene`
|
||||||
|
- `composer.unbind_scene`
|
||||||
|
- `composer.set_camera`
|
||||||
|
- `composer.emit_sprite`
|
||||||
|
- Remove `gfx.set_sprite` from the public syscall contract and registry.
|
||||||
|
- Keep syscall metadata explicit for arg/ret slots and capability requirements.
|
||||||
|
|
||||||
|
**File(s):**
|
||||||
|
- `crates/console/prometeu-hal/src/syscalls.rs`
|
||||||
|
- `crates/console/prometeu-hal/src/syscalls/domains/*`
|
||||||
|
- `crates/console/prometeu-hal/src/syscalls/registry.rs`
|
||||||
|
- `crates/console/prometeu-hal/src/syscalls/resolver.rs`
|
||||||
|
|
||||||
|
### Step 2 - Introduce `ComposerOpStatus`
|
||||||
|
|
||||||
|
**What:**
|
||||||
|
Create the status family for composer-domain mutating operations.
|
||||||
|
|
||||||
|
**How:**
|
||||||
|
- Define a `ComposerOpStatus` type in HAL with explicit operational states needed by:
|
||||||
|
- scene binding
|
||||||
|
- scene unbinding
|
||||||
|
- sprite emission
|
||||||
|
- Ensure the enum is semantically composer-domain specific rather than a rename wrapper around `GfxOpStatus`.
|
||||||
|
- Update public API references so composer syscalls return `ComposerOpStatus` where required by `DEC-0015`.
|
||||||
|
|
||||||
|
**File(s):**
|
||||||
|
- `crates/console/prometeu-hal/src/*`
|
||||||
|
- any shared status exports used by runtime/VM code
|
||||||
|
|
||||||
|
### Step 3 - Propagate the contract into spec, ABI docs, and `ISA_CORE`
|
||||||
|
|
||||||
|
**What:**
|
||||||
|
Update normative documentation so the public contract no longer describes legacy `gfx.set_sprite`.
|
||||||
|
|
||||||
|
**How:**
|
||||||
|
- Identify canonical spec files that describe VM graphics/composition syscalls.
|
||||||
|
- Replace public references to legacy sprite orchestration with `composer.*`.
|
||||||
|
- Update ABI-facing docs to pin:
|
||||||
|
- namespace
|
||||||
|
- names
|
||||||
|
- arg order
|
||||||
|
- return semantics
|
||||||
|
- Update `ISA_CORE` if and where it references the affected syscall surface.
|
||||||
|
- Keep published spec content in English per repository policy.
|
||||||
|
|
||||||
|
**File(s):**
|
||||||
|
- canonical spec location(s)
|
||||||
|
- ABI contract documentation
|
||||||
|
- `ISA_CORE` artifact(s) if affected
|
||||||
|
|
||||||
|
## Test Requirements
|
||||||
|
|
||||||
|
### Unit Tests
|
||||||
|
- syscall registry tests pin the new `composer.*` entries and reject removed legacy identities
|
||||||
|
- `ComposerOpStatus` values are pinned where public return semantics are asserted
|
||||||
|
|
||||||
|
### Integration Tests
|
||||||
|
- declared syscall resolution accepts `composer.*` declarations and rejects removed `gfx.set_sprite`
|
||||||
|
|
||||||
|
### Manual Verification
|
||||||
|
- inspect canonical spec, ABI docs, and `ISA_CORE` references to confirm the public contract matches `DEC-0015`
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- [ ] The public syscall registry exposes `composer.bind_scene`, `composer.unbind_scene`, `composer.set_camera`, and `composer.emit_sprite`.
|
||||||
|
- [ ] `ComposerOpStatus` exists as the canonical status family for composer-domain mutating syscalls.
|
||||||
|
- [ ] `gfx.set_sprite` is removed from the public ABI contract.
|
||||||
|
- [ ] Canonical spec documentation is updated to describe `composer.*`.
|
||||||
|
- [ ] ABI-facing docs and `ISA_CORE` are updated wherever the affected public surface is documented.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- Source decision: `DEC-0015`
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
|
||||||
|
- Missing a normative doc location would leave the code and published contract divergent.
|
||||||
|
- Reusing `GfxOpStatus` semantics by accident would weaken the service-boundary separation required by `DEC-0015`.
|
||||||
|
- Removing the legacy syscall contract incompletely could leave resolver or ABI ambiguity behind.
|
||||||
@ -0,0 +1,112 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0023
|
||||||
|
ticket: frame-composer-public-syscall-surface
|
||||||
|
title: Plan - Composer Runtime Dispatch and Legacy Removal
|
||||||
|
status: accepted
|
||||||
|
created: 2026-04-17
|
||||||
|
completed:
|
||||||
|
tags: [runtime, syscall, frame-composer, dispatch, migration]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Objective
|
||||||
|
|
||||||
|
Route the new public `composer.*` syscalls through `FrameComposer`, remove legacy `gfx.set_sprite` handling, and align runtime-side operational behavior with `DEC-0015`.
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
`DEC-0015` closes the public contract around `composer.*` and requires that `gfx.set_sprite` be removed completely rather than kept as a compatibility shim. The internal `FrameComposer` ownership model already exists from `DEC-0014` and plans `PLN-0017` through `PLN-0021`.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
### Included
|
||||||
|
- runtime syscall dispatch for `composer.*`
|
||||||
|
- operational mapping from syscall args to `FrameComposer`
|
||||||
|
- removal of legacy `gfx.set_sprite` runtime handling
|
||||||
|
- runtime-facing tests for composer-domain behavior
|
||||||
|
|
||||||
|
### Excluded
|
||||||
|
- spec and ABI doc propagation
|
||||||
|
- cartridge/tooling migration
|
||||||
|
- final `make ci` closure
|
||||||
|
|
||||||
|
## Execution Steps
|
||||||
|
|
||||||
|
### Step 1 - Add runtime dispatch for `composer.*`
|
||||||
|
|
||||||
|
**What:**
|
||||||
|
Teach VM runtime dispatch to call `FrameComposer` through the new public contract.
|
||||||
|
|
||||||
|
**How:**
|
||||||
|
- Add dispatch arms for:
|
||||||
|
- `composer.bind_scene`
|
||||||
|
- `composer.unbind_scene`
|
||||||
|
- `composer.set_camera`
|
||||||
|
- `composer.emit_sprite`
|
||||||
|
- Parse arguments exactly as pinned by the HAL metadata.
|
||||||
|
- Return `ComposerOpStatus` for mutating composer-domain syscalls.
|
||||||
|
|
||||||
|
**File(s):**
|
||||||
|
- `crates/console/prometeu-system/src/virtual_machine_runtime/dispatch.rs`
|
||||||
|
- any adjacent runtime helpers
|
||||||
|
|
||||||
|
### Step 2 - Map operational outcomes cleanly onto `ComposerOpStatus`
|
||||||
|
|
||||||
|
**What:**
|
||||||
|
Make runtime failures and normal outcomes reflect the new composer-domain status model.
|
||||||
|
|
||||||
|
**How:**
|
||||||
|
- Bind runtime-side operational checks to status outcomes such as:
|
||||||
|
- scene bank unavailable
|
||||||
|
- bank invalid
|
||||||
|
- argument range invalid
|
||||||
|
- layer invalid
|
||||||
|
- sprite overflow if surfaced operationally
|
||||||
|
- Keep non-fatal overflow behavior aligned with `DEC-0015`.
|
||||||
|
|
||||||
|
**File(s):**
|
||||||
|
- `crates/console/prometeu-system/src/virtual_machine_runtime/dispatch.rs`
|
||||||
|
- `crates/console/prometeu-hal/src/*` as needed for shared status meaning
|
||||||
|
|
||||||
|
### Step 3 - Remove legacy `gfx.set_sprite` runtime support
|
||||||
|
|
||||||
|
**What:**
|
||||||
|
Delete the old public runtime path for slot-style sprite submission.
|
||||||
|
|
||||||
|
**How:**
|
||||||
|
- Remove dispatch support for `gfx.set_sprite`.
|
||||||
|
- Remove runtime assumptions about `active`, caller-provided indices, and legacy sprite ABI shape.
|
||||||
|
- Keep no private compatibility hook behind the public API.
|
||||||
|
|
||||||
|
**File(s):**
|
||||||
|
- `crates/console/prometeu-system/src/virtual_machine_runtime/dispatch.rs`
|
||||||
|
- adjacent tests and public syscall references
|
||||||
|
|
||||||
|
## Test Requirements
|
||||||
|
|
||||||
|
### Unit Tests
|
||||||
|
- runtime dispatch returns `ComposerOpStatus` for bind, unbind, and emit operations
|
||||||
|
- `composer.set_camera` stores the minimal V1 camera coordinates correctly
|
||||||
|
|
||||||
|
### Integration Tests
|
||||||
|
- a VM/runtime test can bind a scene, set camera, emit a sprite, reach `FRAME_SYNC`, and render through the canonical frame path
|
||||||
|
- public runtime behavior rejects removed `gfx.set_sprite` declarations/calls
|
||||||
|
|
||||||
|
### Manual Verification
|
||||||
|
- inspect dispatch code to confirm all public orchestration now routes through `FrameComposer` rather than a legacy `gfx` sprite syscall path
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- [ ] Runtime dispatch supports all canonical `composer.*` syscalls.
|
||||||
|
- [ ] Mutating composer-domain calls return `ComposerOpStatus`.
|
||||||
|
- [ ] `gfx.set_sprite` is removed from runtime public handling.
|
||||||
|
- [ ] Runtime tests cover scene bind, camera set, sprite emit, and frame rendering through the public path.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- Depends on `PLN-0022`
|
||||||
|
- Source decision: `DEC-0015`
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
|
||||||
|
- Removing legacy handling before all runtime references are migrated can strand tests or bytecode fixtures.
|
||||||
|
- Poor `ComposerOpStatus` mapping could collapse useful operational distinctions into generic failures.
|
||||||
@ -0,0 +1,107 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0024
|
||||||
|
ticket: frame-composer-public-syscall-surface
|
||||||
|
title: Plan - Composer Cartridge, Tooling, and Regression Migration
|
||||||
|
status: accepted
|
||||||
|
created: 2026-04-17
|
||||||
|
completed:
|
||||||
|
tags: [runtime, bytecode, tooling, stress, regression, frame-composer]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Objective
|
||||||
|
|
||||||
|
Migrate bytecode declarations, cartridges, stress tooling, and regression coverage from legacy public sprite orchestration to the canonical `composer.*` surface.
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
`DEC-0015` requires the new public composer-domain ABI to land without leaving `gfx.set_sprite` as a fallback. That means the migration must cover the generated bytecode, test cartridges, and stress tooling that still assume the old public contract.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
### Included
|
||||||
|
- bytecode declaration updates for `composer.*`
|
||||||
|
- cartridge and stress generator migration
|
||||||
|
- regression coverage for the public composer-domain path
|
||||||
|
- removal of legacy syscall usage from test and tooling surfaces
|
||||||
|
|
||||||
|
### Excluded
|
||||||
|
- canonical spec propagation
|
||||||
|
- runtime dispatch implementation
|
||||||
|
- final repository-wide CI closure
|
||||||
|
|
||||||
|
## Execution Steps
|
||||||
|
|
||||||
|
### Step 1 - Migrate declared syscall users and fixtures
|
||||||
|
|
||||||
|
**What:**
|
||||||
|
Update code and fixtures that declare public syscalls so they target `composer.*`.
|
||||||
|
|
||||||
|
**How:**
|
||||||
|
- Replace legacy public sprite syscall declarations with composer-domain declarations.
|
||||||
|
- Update ABI expectations in bytecode-related tests and fixtures.
|
||||||
|
- Ensure removal of `gfx.set_sprite` is reflected in any declaration validation snapshots.
|
||||||
|
|
||||||
|
**File(s):**
|
||||||
|
- bytecode tests and fixtures
|
||||||
|
- syscall declaration users across runtime and tools
|
||||||
|
|
||||||
|
### Step 2 - Migrate stress and cartridge tooling
|
||||||
|
|
||||||
|
**What:**
|
||||||
|
Make the stress cartridge and related generators exercise the canonical public frame path.
|
||||||
|
|
||||||
|
**How:**
|
||||||
|
- Update `pbxgen-stress` and any cartridge generators to declare and call `composer.*`.
|
||||||
|
- Replace legacy sprite-path usage with `composer.emit_sprite`.
|
||||||
|
- Add scene bind and camera usage where needed so the stress path reaches the real canonical pipeline.
|
||||||
|
|
||||||
|
**File(s):**
|
||||||
|
- `crates/tools/pbxgen-stress/src/*`
|
||||||
|
- `test-cartridges/stress-console/*`
|
||||||
|
- related scripts such as `scripts/run-stress.sh`
|
||||||
|
|
||||||
|
### Step 3 - Expand regression coverage around the public path
|
||||||
|
|
||||||
|
**What:**
|
||||||
|
Lock the new public orchestration contract with regression tests.
|
||||||
|
|
||||||
|
**How:**
|
||||||
|
- Add tests that cover:
|
||||||
|
- composer-domain declaration resolution
|
||||||
|
- public bind/unbind/camera/emit behavior
|
||||||
|
- scene rendering through the public path
|
||||||
|
- stress/tooling integration using `composer.*`
|
||||||
|
- Ensure no regression fixture still relies on removed `gfx.set_sprite`.
|
||||||
|
|
||||||
|
**File(s):**
|
||||||
|
- runtime tests
|
||||||
|
- HAL syscall tests
|
||||||
|
- tooling tests where available
|
||||||
|
|
||||||
|
## Test Requirements
|
||||||
|
|
||||||
|
### Unit Tests
|
||||||
|
- bytecode and syscall declaration tests pin `composer.*` names and slot counts
|
||||||
|
|
||||||
|
### Integration Tests
|
||||||
|
- stress or cartridge-facing tests exercise scene bind, camera set, and sprite emit through `composer.*`
|
||||||
|
- regression fixtures fail if `gfx.set_sprite` is reintroduced
|
||||||
|
|
||||||
|
### Manual Verification
|
||||||
|
- inspect generated stress cartridge declarations and program behavior to confirm the public path is truly composer-domain based
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- [ ] Bytecode declarations and fixtures use `composer.*` instead of legacy public sprite orchestration.
|
||||||
|
- [ ] Stress tooling and test cartridges exercise the canonical public `FrameComposer` path.
|
||||||
|
- [ ] Regression coverage protects against fallback to `gfx.set_sprite`.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- Depends on `PLN-0022` and `PLN-0023`
|
||||||
|
- Source decision: `DEC-0015`
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
|
||||||
|
- Partial cartridge/tooling migration could leave the repository with hidden legacy public ABI usage.
|
||||||
|
- Stress tooling may appear to pass while still missing scene/camera coverage if it only migrates sprite calls.
|
||||||
@ -0,0 +1,96 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0025
|
||||||
|
ticket: frame-composer-public-syscall-surface
|
||||||
|
title: Plan - Final CI Validation and Polish
|
||||||
|
status: accepted
|
||||||
|
created: 2026-04-17
|
||||||
|
completed:
|
||||||
|
tags: [ci, validation, regression, polish]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Objective
|
||||||
|
|
||||||
|
Run the final repository validation path, including `make ci`, and perform the last compatibility, formatting, lint, and regression fixes required to close the composer-domain migration cleanly.
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
`DEC-0015` requires a coordinated migration across ABI, runtime, tooling, cartridges, spec, and documentation. After the implementation plans land, the repository still needs a final closure pass so no residual breakage survives in formatting, linting, tests, generated artifacts, or CI expectations.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
### Included
|
||||||
|
- final repository validation with `make ci`
|
||||||
|
- fixups required by formatting, lint, tests, snapshots, or generated artifacts
|
||||||
|
- final consistency pass across migrated files
|
||||||
|
|
||||||
|
### Excluded
|
||||||
|
- introducing new contract changes beyond `DEC-0015`
|
||||||
|
- reopening ABI or service-boundary decisions
|
||||||
|
|
||||||
|
## Execution Steps
|
||||||
|
|
||||||
|
### Step 1 - Run the final validation entrypoint
|
||||||
|
|
||||||
|
**What:**
|
||||||
|
Execute the repository’s final CI validation path.
|
||||||
|
|
||||||
|
**How:**
|
||||||
|
- Run `make ci` after `PLN-0022`, `PLN-0023`, and `PLN-0024` are complete.
|
||||||
|
- Capture failures from formatting, lint, tests, coverage setup, generation steps, or artifact drift.
|
||||||
|
|
||||||
|
**File(s):**
|
||||||
|
- repository-wide validation entrypoints
|
||||||
|
|
||||||
|
### Step 2 - Apply closure fixes without reopening scope
|
||||||
|
|
||||||
|
**What:**
|
||||||
|
Resolve residual breakage surfaced by final validation.
|
||||||
|
|
||||||
|
**How:**
|
||||||
|
- Fix formatting and lint issues.
|
||||||
|
- Update snapshots or generated artifacts only where the migrated public contract requires it.
|
||||||
|
- Repair any remaining tests or documentation references that fail under `make ci`.
|
||||||
|
- Do not widen scope beyond the accepted composer-domain migration.
|
||||||
|
|
||||||
|
**File(s):**
|
||||||
|
- any files directly implicated by final validation failures
|
||||||
|
|
||||||
|
### Step 3 - Confirm final repository consistency
|
||||||
|
|
||||||
|
**What:**
|
||||||
|
Leave the migration in a stable publishable state.
|
||||||
|
|
||||||
|
**How:**
|
||||||
|
- Re-run `make ci` until it passes cleanly.
|
||||||
|
- Verify no legacy public `gfx.set_sprite` usage remains in code, tests, tooling, or docs.
|
||||||
|
- Confirm the worktree reflects only intended migration changes.
|
||||||
|
|
||||||
|
**File(s):**
|
||||||
|
- repository-wide
|
||||||
|
|
||||||
|
## Test Requirements
|
||||||
|
|
||||||
|
### Unit Tests
|
||||||
|
- whatever unit coverage is exercised by `make ci` must remain green
|
||||||
|
|
||||||
|
### Integration Tests
|
||||||
|
- repository integration coverage under `make ci` must pass after the migration
|
||||||
|
|
||||||
|
### Manual Verification
|
||||||
|
- inspect the tree for residual `gfx.set_sprite` references and incomplete composer-domain propagation
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- [ ] `make ci` passes after the composer-domain migration family lands.
|
||||||
|
- [ ] Final fixups do not reopen contract scope beyond `DEC-0015`.
|
||||||
|
- [ ] No residual public `gfx.set_sprite` usage remains in the repository.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- Depends on `PLN-0022`, `PLN-0023`, and `PLN-0024`
|
||||||
|
- Source decision: `DEC-0015`
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
|
||||||
|
- If this final closure pass is skipped, small residual regressions can survive across formatting, lint, or generated artifacts even when the core implementation is correct.
|
||||||
|
- Late fixes can accidentally widen scope unless kept strictly bounded to validation fallout.
|
||||||
Loading…
x
Reference in New Issue
Block a user