7.8 KiB
| id | ticket | title | status | created | accepted | agenda | plans | tags | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| DEC-0015 | frame-composer-public-syscall-surface | FrameComposer Public Syscall Surface | accepted | 2026-04-17 | 2026-04-17 | AGD-0027 |
|
|
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
FrameComposeroperations SHALL becomposer. - The initial canonical syscall set SHALL be:
composer.bind_scene(bank_id) -> ComposerOpStatuscomposer.unbind_scene() -> ComposerOpStatuscomposer.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 carrylayerandpriority.composer.emit_sprite(...)MUST NOT exposeactiveas part of the canonical contract.composer.bind_scene(...),composer.unbind_scene(), andcomposer.emit_sprite(...)SHALL returnComposerOpStatus.composer.set_camera(x, y)SHALL keep the minimal V1 camera contract already accepted byDEC-0014:xandyarei32pixel 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 ofgfx.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:
Gfxis the visual backend;FrameComposeris 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.ComposerOpStatusSHALL 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_idpalette_idxylayerbank_idflip_xflip_ypriority
- 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
composerdomain surface. gfx.set_sprite(...)must be removed from the public ABI contract.- A new
ComposerOpStatuscontract 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_COREmust be updated if and where it normatively references the public syscall surface affected by this decision.
Drivers / Hardware
FrameComposeralready 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
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_COREartifacts 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.