2.9 KiB
| id | ticket | title | created | tags | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| LSN-0032 | frame-composer-public-syscall-surface | Public ABI Must Follow the Canonical Service Boundary | 2026-04-18 |
|
Context
DSC-0026 finished the internal migration to FrameComposer as the canonical frame-orchestration owner, but the public VM-facing ABI still exposed part of that behavior through legacy gfx-domain calls. That left the codebase with a mismatch between the real runtime ownership model and the surface visible to cartridges, tooling, and syscall declarations.
DSC-0027 closed that gap by introducing the composer.* public domain and removing the old public sprite path.
Key Decisions
Public Syscalls Must Expose the Real Owner
What:
Scene binding, camera control, and sprite emission now live under composer.*, and the legacy public gfx.set_sprite path is gone.
Why:
Once FrameComposer became the canonical orchestration service, keeping public orchestration under gfx.* would preserve the wrong mental model and encourage callers to treat the render backend as the owner of frame policy.
Trade-offs: This forces migration across ABI declarations, runtime dispatch, tests, and tooling, but it removes the long-term cost of a misleading public boundary.
Domain-Specific Status Types Preserve Architectural Meaning
What:
Mutating public composer operations return ComposerOpStatus instead of reusing backend-oriented status naming.
Why:
Operational outcomes for scene binding or sprite emission are not backend-domain results. Reusing GfxOpStatus would blur the boundary that the migration was trying to make explicit.
Trade-offs: This adds one more status family to maintain, but it keeps the public ABI semantically aligned with the actual service contract.
Patterns and Algorithms
- Promote internal ownership changes into the public ABI as part of the same migration thread.
- Use syscall domains to encode service boundaries, not just namespace aesthetics.
- Remove obsolete public fallbacks completely when they preserve the wrong operational model.
- Keep runtime dispatch, bytecode declarations, and tooling aligned so the public path is exercised end to end.
Pitfalls
- Leaving a legacy public syscall alive after the internal model changes creates a dual-contract system that is harder to remove later.
- Migrating runtime dispatch without migrating declarations and tooling can leave hidden ABI drift in tests and generators.
- Reusing backend-specific status names in the wrong domain quietly leaks old ownership assumptions into new APIs.
Takeaways
- The public ABI should mirror the canonical service boundary, not historical implementation leftovers.
- Namespace changes are architectural when they change who is responsible for a behavior.
- Removing a legacy public entrypoint is often safer than preserving a compatibility shim that encodes the wrong model.