prometeu-runtime/discussion/workflow/decisions/DEC-0015-frame-composer-public-syscall-surface.md

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
PLN-0022
PLN-0023
PLN-0024
PLN-0025
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

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.